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,
}
#[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();
+58 -45
View File
@@ -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<Box<dyn Reflect>> {
fn variants(&self) -> Vec<(&str, Box<dyn Reflect>)> {
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<alloc::string::String> = (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<dyn Reflect> = 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<alloc::string::String> = (&l as &dyn ToCsv).enumerate();
for entry in &mut field_csvs {
*entry = format!("{}.{}", #variant_name_s, &entry);
}
values.extend(field_csvs);
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! {
impl ToCsv for #name {
fn to_csv(&self) -> alloc::vec::Vec<alloc::string::String> {
extern crate alloc;
use alloc::format;
let mut values: alloc::vec::Vec<alloc::string::String> = 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<dyn Reflect>)> {
let mut variants = Vec::new();
#(#variant_arms)*
variants
}
fn enumerate(&self) -> alloc::vec::Vec<alloc::string::String> {
extern crate alloc;
use alloc::format;
let mut values:alloc::vec::Vec<alloc::string::String> = alloc::vec::Vec::new();
#(#arms_enum)*
return values;
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;
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<ReflectValue>),
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<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) {
@@ -123,9 +165,103 @@ impl Reflect for u8 {
ReflectValue::U8(*self)
}
fn variants(&self) -> Vec<Box<dyn Reflect>> {
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 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 {
@@ -149,108 +285,164 @@ impl Reflect for i8 {
ReflectValue::I8(*self)
}
fn variants(&self) -> Vec<Box<dyn Reflect>> {
fn variants(&self) -> Vec<(&str, Box<dyn Reflect>)> {
Vec::new()
}
fn as_variant(&mut self, _i: usize) -> Option<&mut dyn Reflect> {
None
}
}
// pub trait ToCsvClean {
// fn to_csv_clean(&self) -> Vec<String>;
// fn enumerate_clean(&self) -> Vec<String>;
// }
impl Reflect for i16 {
fn reflect_type(&self) -> ReflectType {
ReflectType::Value
}
// impl ToCsv for u8 {
// fn to_csv(&self) -> Vec<String> {
// vec![format!(" = {}", self)]
// }
fn type_name(&self) -> &str {
"i16"
}
// fn enumerate(&self) -> Vec<String> {
// vec![format!(" = u8")]
// }
// }
fn fields(&mut self) -> Vec<(&str, &mut dyn Reflect)> {
Vec::new()
}
// impl ToCsv for i8 {
// fn to_csv(&self) -> Vec<String> {
// vec![format!(" = {}", self)]
// }
fn set_value(&mut self, value: ReflectValue) {
*self = value.signed() as Self;
}
// fn enumerate(&self) -> Vec<String> {
// vec![format!(" = i8")]
// }
// }
fn get_value(&self) -> ReflectValue {
ReflectValue::I16(*self)
}
// impl ToCsv for u16 {
// fn to_csv(&self) -> Vec<String> {
// vec![format!(" = {}", self)]
// }
fn variants(&self) -> Vec<(&str, Box<dyn Reflect>)> {
Vec::new()
}
// fn enumerate(&self) -> Vec<String> {
// vec![format!(" = u16")]
// }
// }
fn as_variant(&mut self, _i: usize) -> Option<&mut dyn Reflect> {
None
}
}
// impl ToCsv for i16 {
// fn to_csv(&self) -> Vec<String> {
// vec![format!(" = {}", self)]
// }
// fn enumerate(&self) -> Vec<String> {
// vec![format!(" = i16")]
// }
// }
impl Reflect for i32 {
fn reflect_type(&self) -> ReflectType {
ReflectType::Value
}
// impl ToCsv for u32 {
// fn to_csv(&self) -> Vec<String> {
// vec![format!(" = {}", self)]
// }
// fn enumerate(&self) -> Vec<String> {
// vec![format!(" = u32")]
// }
// }
fn type_name(&self) -> &str {
"i32"
}
// impl ToCsv for i32 {
// fn to_csv(&self) -> Vec<String> {
// vec![format!(" = {}", self)]
// }
// fn enumerate(&self) -> Vec<String> {
// vec![format!(" = i32")]
// }
// }
fn fields(&mut self) -> Vec<(&str, &mut dyn Reflect)> {
Vec::new()
}
// impl ToCsv for u64 {
// fn to_csv(&self) -> Vec<String> {
// vec![format!(" = {}", self)]
// }
// fn enumerate(&self) -> Vec<String> {
// vec![format!(" = u64")]
// }
// }
fn set_value(&mut self, value: ReflectValue) {
*self = value.signed() as Self;
}
// impl ToCsv for i64 {
// fn to_csv(&self) -> Vec<String> {
// vec![format!(" = {}", self)]
// }
// fn enumerate(&self) -> Vec<String> {
// vec![format!(" = i64")]
// }
// }
fn get_value(&self) -> ReflectValue {
ReflectValue::I32(*self)
}
// impl ToCsv for &str {
// fn to_csv(&self) -> Vec<String> {
// vec![format!(" = {}", self)]
// }
// fn enumerate(&self) -> Vec<String> {
// vec![format!(" = String")]
// }
// }
fn variants(&self) -> Vec<(&str, Box<dyn Reflect>)> {
Vec::new()
}
// impl ToCsv for String {
// fn to_csv(&self) -> Vec<String> {
// vec![format!(" = {}", self)]
// }
// fn enumerate(&self) -> Vec<String> {
// 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<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 {
// fn to_csv(&self) -> Vec<String> {