diff --git a/builds/ground/src/main.rs b/builds/ground/src/main.rs index 847c2af..1d844b9 100644 --- a/builds/ground/src/main.rs +++ b/builds/ground/src/main.rs @@ -101,6 +101,13 @@ struct TestStruct { counter: i8, } +#[derive(Debug, Default, Reflect)] +enum EnumTest { + #[default] + None, + Test(TestStruct), +} + fn main() -> Result<()> { SimpleLogger::new() .with_level(LevelFilter::Debug) @@ -117,9 +124,20 @@ fn main() -> Result<()> { ); let mut test = TestStruct::default(); - info!("{:?}", test); + info!("{:?}", test.fields()); 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(|| { // let mut udp = UdpConnector::new("127.0.0.1", 7011, "127.0.0.1", 7010).unwrap(); diff --git a/rfe/macros/src/macros.rs b/rfe/macros/src/macros.rs index b6c426e..7fdcdb2 100644 --- a/rfe/macros/src/macros.rs +++ b/rfe/macros/src/macros.rs @@ -313,12 +313,16 @@ pub fn reflect_derive(input: TokenStream) -> TokenStream { } fn get_value(&self) -> ReflectValue { - ReflectValue::Str("".to_string()) + ReflectValue::None } - fn variants(&self) -> Vec> { + fn variants(&self) -> Vec<(&str, Box)> { 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) => { 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_s = variant_name.to_string(); match &variant.fields { 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 => {}, } } Fields::Unnamed(_) => { - quote! {Self::#variant_name(l) => { - let mut field_csvs: alloc::vec::Vec = (l as &dyn ToCsv).to_csv(); - for entry in &mut field_csvs { - *entry = format!("{}.{}", #variant_name_s, &entry); - } - values.extend(field_csvs); - },} + quote! { + if _i == #i { + *self = Self::#variant_name(Default::default()); + if let Self::#variant_name(r) = self { + return Some(r); + } + } + } } Fields::Named(_) => { 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_s = variant_name.to_string(); match &variant.fields { Fields::Unit => { - quote! { values.push(format!(" = {}::{}", #name_s, #variant_name_s)); } + quote! { + { + let value: Box = Box::new(Self::#variant_name); + variants.push((#variant_name_s, value)); + } + } } - Fields::Unnamed(var) => { - let var_type = - if let Some(first_field) = var.unnamed.first() { - first_field - } else { - panic!("Struct has no fields!"); - }; + Fields::Unnamed(_) => { quote! { { - let l = #var_type::default(); - let mut field_csvs: alloc::vec::Vec = (&l as &dyn ToCsv).enumerate(); - - for entry in &mut field_csvs { - *entry = format!("{}.{}", #variant_name_s, &entry); - } - values.extend(field_csvs); + let value: Box = 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! { - impl ToCsv for #name { - fn to_csv(&self) -> alloc::vec::Vec { - extern crate alloc; - use alloc::format; - let mut values: alloc::vec::Vec = alloc::vec::Vec::new(); - - match self { - #(#arms)* - } - return values; + impl Reflect for #name { + fn reflect_type(&self) -> ReflectType { + ReflectType::Enumeration + } + + fn type_name(&self) -> &str { + #name_s + } + + fn fields(&mut self) -> Vec<(&str, &mut dyn Reflect)> { + Vec::new() + } + + fn set_value(&mut self, value: ReflectValue) { + } + + fn get_value(&self) -> ReflectValue { + ReflectValue::None + } + + fn variants(&self) -> Vec<(&str, Box)> { + let mut variants = Vec::new(); + #(#variant_arms)* + variants } - fn enumerate(&self) -> alloc::vec::Vec { - extern crate alloc; - use alloc::format; - - let mut values:alloc::vec::Vec = alloc::vec::Vec::new(); - #(#arms_enum)* - return values; - + fn as_variant(&mut self, _i: usize) -> Option<&mut dyn Reflect> { + #(#as_arms)* + panic!("variant incorrect"); } } } diff --git a/rfe/src/reflect.rs b/rfe/src/reflect.rs index 0d5fed9..f06d192 100644 --- a/rfe/src/reflect.rs +++ b/rfe/src/reflect.rs @@ -1,4 +1,6 @@ extern crate alloc; +use std::string::ToString; + use alloc::boxed::Box; use alloc::string::String; use alloc::vec::Vec; @@ -21,6 +23,7 @@ pub enum ReflectValue { I64(i64), Vec(Vec), Str(String), + Bool(bool), } impl ReflectValue { @@ -37,6 +40,13 @@ impl ReflectValue { ReflectValue::I64(v) => *v as i64, ReflectValue::Vec(_) => 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::Vec(_) => 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 set_value(&mut self, value: ReflectValue); fn get_value(&self) -> ReflectValue; - fn variants(&self) -> Vec>; + fn variants(&self) -> Vec<(&str, Box)>; + fn as_variant(&mut self, i: usize) -> Option<&mut dyn Reflect>; } pub fn path_set(reflect: &mut dyn Reflect, path: &str, value: ReflectValue) { @@ -123,9 +165,103 @@ impl Reflect for u8 { ReflectValue::U8(*self) } - fn variants(&self) -> Vec> { + fn variants(&self) -> Vec<(&str, Box)> { 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)> { + 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)> { + 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)> { + Vec::new() + } + + fn as_variant(&mut self, _i: usize) -> Option<&mut dyn Reflect> { + None + } } impl Reflect for i8 { @@ -149,108 +285,164 @@ impl Reflect for i8 { ReflectValue::I8(*self) } - fn variants(&self) -> Vec> { + fn variants(&self) -> Vec<(&str, Box)> { Vec::new() } + + fn as_variant(&mut self, _i: usize) -> Option<&mut dyn Reflect> { + None + } } -// pub trait ToCsvClean { -// fn to_csv_clean(&self) -> Vec; -// fn enumerate_clean(&self) -> Vec; -// } +impl Reflect for i16 { + fn reflect_type(&self) -> ReflectType { + ReflectType::Value + } -// impl ToCsv for u8 { -// fn to_csv(&self) -> Vec { -// vec![format!(" = {}", self)] -// } + fn type_name(&self) -> &str { + "i16" + } -// fn enumerate(&self) -> Vec { -// vec![format!(" = u8")] -// } -// } + fn fields(&mut self) -> Vec<(&str, &mut dyn Reflect)> { + Vec::new() + } -// impl ToCsv for i8 { -// fn to_csv(&self) -> Vec { -// vec![format!(" = {}", self)] -// } + fn set_value(&mut self, value: ReflectValue) { + *self = value.signed() as Self; + } -// fn enumerate(&self) -> Vec { -// vec![format!(" = i8")] -// } -// } + fn get_value(&self) -> ReflectValue { + ReflectValue::I16(*self) + } -// impl ToCsv for u16 { -// fn to_csv(&self) -> Vec { -// vec![format!(" = {}", self)] -// } + fn variants(&self) -> Vec<(&str, Box)> { + Vec::new() + } -// fn enumerate(&self) -> Vec { -// vec![format!(" = u16")] -// } -// } + fn as_variant(&mut self, _i: usize) -> Option<&mut dyn Reflect> { + None + } +} -// impl ToCsv for i16 { -// fn to_csv(&self) -> Vec { -// vec![format!(" = {}", self)] -// } -// fn enumerate(&self) -> Vec { -// vec![format!(" = i16")] -// } -// } +impl Reflect for i32 { + fn reflect_type(&self) -> ReflectType { + ReflectType::Value + } -// impl ToCsv for u32 { -// fn to_csv(&self) -> Vec { -// vec![format!(" = {}", self)] -// } -// fn enumerate(&self) -> Vec { -// vec![format!(" = u32")] -// } -// } + fn type_name(&self) -> &str { + "i32" + } -// impl ToCsv for i32 { -// fn to_csv(&self) -> Vec { -// vec![format!(" = {}", self)] -// } -// fn enumerate(&self) -> Vec { -// vec![format!(" = i32")] -// } -// } + fn fields(&mut self) -> Vec<(&str, &mut dyn Reflect)> { + Vec::new() + } -// impl ToCsv for u64 { -// fn to_csv(&self) -> Vec { -// vec![format!(" = {}", self)] -// } -// fn enumerate(&self) -> Vec { -// vec![format!(" = u64")] -// } -// } + fn set_value(&mut self, value: ReflectValue) { + *self = value.signed() as Self; + } -// impl ToCsv for i64 { -// fn to_csv(&self) -> Vec { -// vec![format!(" = {}", self)] -// } -// fn enumerate(&self) -> Vec { -// vec![format!(" = i64")] -// } -// } + fn get_value(&self) -> ReflectValue { + ReflectValue::I32(*self) + } -// impl ToCsv for &str { -// fn to_csv(&self) -> Vec { -// vec![format!(" = {}", self)] -// } -// fn enumerate(&self) -> Vec { -// vec![format!(" = String")] -// } -// } + fn variants(&self) -> Vec<(&str, Box)> { + Vec::new() + } -// impl ToCsv for String { -// fn to_csv(&self) -> Vec { -// vec![format!(" = {}", self)] -// } -// fn enumerate(&self) -> Vec { -// vec![format!(" = String")] -// } -// } + fn as_variant(&mut self, _i: usize) -> Option<&mut dyn Reflect> { + None + } +} + +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)> { + 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)> { + 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)> { + Vec::new() + } + + fn as_variant(&mut self, _i: usize) -> Option<&mut dyn Reflect> { + None + } +} // impl ToCsv for bool { // fn to_csv(&self) -> Vec {