This commit is contained in:
Jacob Weaver
2024-12-18 15:44:02 -06:00
parent c9ad723e79
commit 1a511523f4
3 changed files with 357 additions and 134 deletions
+20 -2
View File
@@ -101,6 +101,13 @@ struct TestStruct {
counter: i8, counter: i8,
} }
#[derive(Debug, Default, Reflect)]
enum EnumTest {
#[default]
None,
Test(TestStruct),
}
fn main() -> Result<()> { fn main() -> Result<()> {
SimpleLogger::new() SimpleLogger::new()
.with_level(LevelFilter::Debug) .with_level(LevelFilter::Debug)
@@ -117,9 +124,20 @@ fn main() -> Result<()> {
); );
let mut test = TestStruct::default(); let mut test = TestStruct::default();
info!("{:?}", test); info!("{:?}", test.fields());
reflect::path_set(&mut test, "counter", ReflectValue::I64(1)); reflect::path_set(&mut test, "counter", ReflectValue::I64(1));
info!("{:?}", test); info!("{:?}", test.fields());
let mut test2 = EnumTest::None;
// info!("{:?}", test2);
// let testref = test2.as_variant(1).unwrap();
// test2.as_variant(1).unwrap().fields()[0]
// .1
// .set_value(ReflectValue::I64(3));
// info!("{:?}", test2);
// spawn(|| { // spawn(|| {
// let mut udp = UdpConnector::new("127.0.0.1", 7011, "127.0.0.1", 7010).unwrap(); // let mut udp = UdpConnector::new("127.0.0.1", 7011, "127.0.0.1", 7010).unwrap();
+55 -42
View File
@@ -313,12 +313,16 @@ pub fn reflect_derive(input: TokenStream) -> TokenStream {
} }
fn get_value(&self) -> ReflectValue { fn get_value(&self) -> ReflectValue {
ReflectValue::Str("".to_string()) ReflectValue::None
} }
fn variants(&self) -> Vec<Box<dyn Reflect>> { fn variants(&self) -> Vec<(&str, Box<dyn Reflect>)> {
Vec::new() Vec::new()
} }
fn as_variant(&mut self, _i: usize) -> Option<&mut dyn Reflect> {
None
}
} }
} }
} }
@@ -329,23 +333,29 @@ pub fn reflect_derive(input: TokenStream) -> TokenStream {
Data::Enum(data_enum) => { Data::Enum(data_enum) => {
let variants = data_enum.variants; let variants = data_enum.variants;
let arms = variants.iter().map(|variant| { let as_arms = variants.iter().enumerate().map(|(i, variant)| {
let variant_name = &variant.ident; let variant_name = &variant.ident;
let variant_name_s = variant_name.to_string(); let variant_name_s = variant_name.to_string();
match &variant.fields { match &variant.fields {
Fields::Unit => { Fields::Unit => {
quote! { Self::#variant_name => values.push(format!(" = {}::{}", #name_s, #variant_name_s)), } quote! {
if _i == #i {
*self = Self::#variant_name;
return Some(self);
}
}
// quote! { Self::#variant_name => {}, } // quote! { Self::#variant_name => {}, }
} }
Fields::Unnamed(_) => { Fields::Unnamed(_) => {
quote! {Self::#variant_name(l) => { quote! {
let mut field_csvs: alloc::vec::Vec<alloc::string::String> = (l as &dyn ToCsv).to_csv(); if _i == #i {
for entry in &mut field_csvs { *self = Self::#variant_name(Default::default());
*entry = format!("{}.{}", #variant_name_s, &entry); if let Self::#variant_name(r) = self {
return Some(r);
}
}
} }
values.extend(field_csvs);
},}
} }
Fields::Named(_) => { Fields::Named(_) => {
panic!("Named fields not supported by ToCsv"); panic!("Named fields not supported by ToCsv");
@@ -353,30 +363,24 @@ pub fn reflect_derive(input: TokenStream) -> TokenStream {
} }
}); });
let arms_enum = variants.iter().map(|variant| { let variant_arms = variants.iter().map(|variant| {
let variant_name = &variant.ident; let variant_name = &variant.ident;
let variant_name_s = variant_name.to_string(); let variant_name_s = variant_name.to_string();
match &variant.fields { match &variant.fields {
Fields::Unit => { Fields::Unit => {
quote! { values.push(format!(" = {}::{}", #name_s, #variant_name_s)); }
}
Fields::Unnamed(var) => {
let var_type =
if let Some(first_field) = var.unnamed.first() {
first_field
} else {
panic!("Struct has no fields!");
};
quote! { quote! {
{ {
let l = #var_type::default(); let value: Box<dyn Reflect> = Box::new(Self::#variant_name);
let mut field_csvs: alloc::vec::Vec<alloc::string::String> = (&l as &dyn ToCsv).enumerate(); variants.push((#variant_name_s, value));
for entry in &mut field_csvs {
*entry = format!("{}.{}", #variant_name_s, &entry);
} }
values.extend(field_csvs); }
}
Fields::Unnamed(_) => {
quote! {
{
let value: Box<dyn Reflect> = Box::new(Self::#variant_name(Default::default()));
variants.push((#variant_name_s, value));
} }
} }
@@ -388,26 +392,35 @@ pub fn reflect_derive(input: TokenStream) -> TokenStream {
}); });
quote! { quote! {
impl ToCsv for #name { impl Reflect for #name {
fn to_csv(&self) -> alloc::vec::Vec<alloc::string::String> { fn reflect_type(&self) -> ReflectType {
extern crate alloc; ReflectType::Enumeration
use alloc::format;
let mut values: alloc::vec::Vec<alloc::string::String> = alloc::vec::Vec::new();
match self {
#(#arms)*
}
return values;
} }
fn enumerate(&self) -> alloc::vec::Vec<alloc::string::String> { fn type_name(&self) -> &str {
extern crate alloc; #name_s
use alloc::format; }
let mut values:alloc::vec::Vec<alloc::string::String> = alloc::vec::Vec::new(); fn fields(&mut self) -> Vec<(&str, &mut dyn Reflect)> {
#(#arms_enum)* Vec::new()
return values; }
fn set_value(&mut self, value: ReflectValue) {
}
fn get_value(&self) -> ReflectValue {
ReflectValue::None
}
fn variants(&self) -> Vec<(&str, Box<dyn Reflect>)> {
let mut variants = Vec::new();
#(#variant_arms)*
variants
}
fn as_variant(&mut self, _i: usize) -> Option<&mut dyn Reflect> {
#(#as_arms)*
panic!("variant incorrect");
} }
} }
} }
+279 -87
View File
@@ -1,4 +1,6 @@
extern crate alloc; extern crate alloc;
use std::string::ToString;
use alloc::boxed::Box; use alloc::boxed::Box;
use alloc::string::String; use alloc::string::String;
use alloc::vec::Vec; use alloc::vec::Vec;
@@ -21,6 +23,7 @@ pub enum ReflectValue {
I64(i64), I64(i64),
Vec(Vec<ReflectValue>), Vec(Vec<ReflectValue>),
Str(String), Str(String),
Bool(bool),
} }
impl ReflectValue { impl ReflectValue {
@@ -37,6 +40,13 @@ impl ReflectValue {
ReflectValue::I64(v) => *v as i64, ReflectValue::I64(v) => *v as i64,
ReflectValue::Vec(_) => 0, ReflectValue::Vec(_) => 0,
ReflectValue::Str(_) => 0, ReflectValue::Str(_) => 0,
ReflectValue::Bool(b) => {
if *b {
1
} else {
0
}
}
} }
} }
@@ -53,6 +63,37 @@ impl ReflectValue {
ReflectValue::I64(v) => *v as u64, ReflectValue::I64(v) => *v as u64,
ReflectValue::Vec(_) => 0, ReflectValue::Vec(_) => 0,
ReflectValue::Str(_) => 0, ReflectValue::Str(_) => 0,
ReflectValue::Bool(b) => {
if *b {
1
} else {
0
}
}
}
}
pub fn str(self) -> String {
match self {
ReflectValue::Str(s) => s,
_ => "".to_string(),
}
}
pub fn bool(&self) -> bool {
match self {
ReflectValue::None => false,
ReflectValue::U8(v) => *v == 0,
ReflectValue::U16(v) => *v == 0,
ReflectValue::U32(v) => *v == 0,
ReflectValue::U64(v) => *v == 0,
ReflectValue::I8(v) => *v == 0,
ReflectValue::I16(v) => *v == 0,
ReflectValue::I32(v) => *v == 0,
ReflectValue::I64(v) => *v == 0,
ReflectValue::Vec(_) => false,
ReflectValue::Str(_) => false,
ReflectValue::Bool(b) => *b,
} }
} }
} }
@@ -63,7 +104,8 @@ pub trait Reflect: std::fmt::Debug {
fn fields(&mut self) -> Vec<(&str, &mut dyn Reflect)>; fn fields(&mut self) -> Vec<(&str, &mut dyn Reflect)>;
fn set_value(&mut self, value: ReflectValue); fn set_value(&mut self, value: ReflectValue);
fn get_value(&self) -> ReflectValue; fn get_value(&self) -> ReflectValue;
fn variants(&self) -> Vec<Box<dyn Reflect>>; fn variants(&self) -> Vec<(&str, Box<dyn Reflect>)>;
fn as_variant(&mut self, i: usize) -> Option<&mut dyn Reflect>;
} }
pub fn path_set(reflect: &mut dyn Reflect, path: &str, value: ReflectValue) { pub fn path_set(reflect: &mut dyn Reflect, path: &str, value: ReflectValue) {
@@ -123,9 +165,103 @@ impl Reflect for u8 {
ReflectValue::U8(*self) ReflectValue::U8(*self)
} }
fn variants(&self) -> Vec<Box<dyn Reflect>> { fn variants(&self) -> Vec<(&str, Box<dyn Reflect>)> {
Vec::new() Vec::new()
} }
fn as_variant(&mut self, _i: usize) -> Option<&mut dyn Reflect> {
None
}
}
impl Reflect for u16 {
fn reflect_type(&self) -> ReflectType {
ReflectType::Value
}
fn type_name(&self) -> &str {
"u16"
}
fn fields(&mut self) -> Vec<(&str, &mut dyn Reflect)> {
Vec::new()
}
fn set_value(&mut self, value: ReflectValue) {
*self = value.unsigned() as Self;
}
fn get_value(&self) -> ReflectValue {
ReflectValue::U16(*self)
}
fn variants(&self) -> Vec<(&str, Box<dyn Reflect>)> {
Vec::new()
}
fn as_variant(&mut self, _i: usize) -> Option<&mut dyn Reflect> {
None
}
}
impl Reflect for u32 {
fn reflect_type(&self) -> ReflectType {
ReflectType::Value
}
fn type_name(&self) -> &str {
"u32"
}
fn fields(&mut self) -> Vec<(&str, &mut dyn Reflect)> {
Vec::new()
}
fn set_value(&mut self, value: ReflectValue) {
*self = value.unsigned() as Self;
}
fn get_value(&self) -> ReflectValue {
ReflectValue::U32(*self)
}
fn variants(&self) -> Vec<(&str, Box<dyn Reflect>)> {
Vec::new()
}
fn as_variant(&mut self, _i: usize) -> Option<&mut dyn Reflect> {
None
}
}
impl Reflect for u64 {
fn reflect_type(&self) -> ReflectType {
ReflectType::Value
}
fn type_name(&self) -> &str {
"u64"
}
fn fields(&mut self) -> Vec<(&str, &mut dyn Reflect)> {
Vec::new()
}
fn set_value(&mut self, value: ReflectValue) {
*self = value.unsigned() as Self;
}
fn get_value(&self) -> ReflectValue {
ReflectValue::U64(*self)
}
fn variants(&self) -> Vec<(&str, Box<dyn Reflect>)> {
Vec::new()
}
fn as_variant(&mut self, _i: usize) -> Option<&mut dyn Reflect> {
None
}
} }
impl Reflect for i8 { impl Reflect for i8 {
@@ -149,108 +285,164 @@ impl Reflect for i8 {
ReflectValue::I8(*self) ReflectValue::I8(*self)
} }
fn variants(&self) -> Vec<Box<dyn Reflect>> { fn variants(&self) -> Vec<(&str, Box<dyn Reflect>)> {
Vec::new() Vec::new()
} }
fn as_variant(&mut self, _i: usize) -> Option<&mut dyn Reflect> {
None
}
} }
// pub trait ToCsvClean { impl Reflect for i16 {
// fn to_csv_clean(&self) -> Vec<String>; fn reflect_type(&self) -> ReflectType {
// fn enumerate_clean(&self) -> Vec<String>; ReflectType::Value
// } }
// impl ToCsv for u8 { fn type_name(&self) -> &str {
// fn to_csv(&self) -> Vec<String> { "i16"
// vec![format!(" = {}", self)] }
// }
// fn enumerate(&self) -> Vec<String> { fn fields(&mut self) -> Vec<(&str, &mut dyn Reflect)> {
// vec![format!(" = u8")] Vec::new()
// } }
// }
// impl ToCsv for i8 { fn set_value(&mut self, value: ReflectValue) {
// fn to_csv(&self) -> Vec<String> { *self = value.signed() as Self;
// vec![format!(" = {}", self)] }
// }
// fn enumerate(&self) -> Vec<String> { fn get_value(&self) -> ReflectValue {
// vec![format!(" = i8")] ReflectValue::I16(*self)
// } }
// }
// impl ToCsv for u16 { fn variants(&self) -> Vec<(&str, Box<dyn Reflect>)> {
// fn to_csv(&self) -> Vec<String> { Vec::new()
// vec![format!(" = {}", self)] }
// }
// fn enumerate(&self) -> Vec<String> { fn as_variant(&mut self, _i: usize) -> Option<&mut dyn Reflect> {
// vec![format!(" = u16")] None
// } }
// } }
// impl ToCsv for i16 { impl Reflect for i32 {
// fn to_csv(&self) -> Vec<String> { fn reflect_type(&self) -> ReflectType {
// vec![format!(" = {}", self)] ReflectType::Value
// } }
// fn enumerate(&self) -> Vec<String> {
// vec![format!(" = i16")]
// }
// }
// impl ToCsv for u32 { fn type_name(&self) -> &str {
// fn to_csv(&self) -> Vec<String> { "i32"
// vec![format!(" = {}", self)] }
// }
// fn enumerate(&self) -> Vec<String> {
// vec![format!(" = u32")]
// }
// }
// impl ToCsv for i32 { fn fields(&mut self) -> Vec<(&str, &mut dyn Reflect)> {
// fn to_csv(&self) -> Vec<String> { Vec::new()
// vec![format!(" = {}", self)] }
// }
// fn enumerate(&self) -> Vec<String> {
// vec![format!(" = i32")]
// }
// }
// impl ToCsv for u64 { fn set_value(&mut self, value: ReflectValue) {
// fn to_csv(&self) -> Vec<String> { *self = value.signed() as Self;
// vec![format!(" = {}", self)] }
// }
// fn enumerate(&self) -> Vec<String> {
// vec![format!(" = u64")]
// }
// }
// impl ToCsv for i64 { fn get_value(&self) -> ReflectValue {
// fn to_csv(&self) -> Vec<String> { ReflectValue::I32(*self)
// vec![format!(" = {}", self)] }
// }
// fn enumerate(&self) -> Vec<String> {
// vec![format!(" = i64")]
// }
// }
// impl ToCsv for &str { fn variants(&self) -> Vec<(&str, Box<dyn Reflect>)> {
// fn to_csv(&self) -> Vec<String> { Vec::new()
// vec![format!(" = {}", self)] }
// }
// fn enumerate(&self) -> Vec<String> {
// vec![format!(" = String")]
// }
// }
// impl ToCsv for String { fn as_variant(&mut self, _i: usize) -> Option<&mut dyn Reflect> {
// fn to_csv(&self) -> Vec<String> { None
// vec![format!(" = {}", self)] }
// } }
// fn enumerate(&self) -> Vec<String> {
// vec![format!(" = String")] impl Reflect for i64 {
// } fn reflect_type(&self) -> ReflectType {
// } ReflectType::Value
}
fn type_name(&self) -> &str {
"i64"
}
fn fields(&mut self) -> Vec<(&str, &mut dyn Reflect)> {
Vec::new()
}
fn set_value(&mut self, value: ReflectValue) {
*self = value.signed() as Self;
}
fn get_value(&self) -> ReflectValue {
ReflectValue::I64(*self)
}
fn variants(&self) -> Vec<(&str, Box<dyn Reflect>)> {
Vec::new()
}
fn as_variant(&mut self, _i: usize) -> Option<&mut dyn Reflect> {
None
}
}
impl Reflect for String {
fn reflect_type(&self) -> ReflectType {
ReflectType::Value
}
fn type_name(&self) -> &str {
"str"
}
fn fields(&mut self) -> Vec<(&str, &mut dyn Reflect)> {
Vec::new()
}
fn set_value(&mut self, value: ReflectValue) {
*self = value.str();
}
fn get_value(&self) -> ReflectValue {
ReflectValue::Str(self.to_string())
}
fn variants(&self) -> Vec<(&str, Box<dyn Reflect>)> {
Vec::new()
}
fn as_variant(&mut self, _i: usize) -> Option<&mut dyn Reflect> {
None
}
}
impl Reflect for bool {
fn reflect_type(&self) -> ReflectType {
ReflectType::Value
}
fn type_name(&self) -> &str {
"bool"
}
fn fields(&mut self) -> Vec<(&str, &mut dyn Reflect)> {
Vec::new()
}
fn set_value(&mut self, value: ReflectValue) {
*self = value.bool();
}
fn get_value(&self) -> ReflectValue {
ReflectValue::Bool(*self)
}
fn variants(&self) -> Vec<(&str, Box<dyn Reflect>)> {
Vec::new()
}
fn as_variant(&mut self, _i: usize) -> Option<&mut dyn Reflect> {
None
}
}
// impl ToCsv for bool { // impl ToCsv for bool {
// fn to_csv(&self) -> Vec<String> { // fn to_csv(&self) -> Vec<String> {