reflect
This commit is contained in:
@@ -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
@@ -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
@@ -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> {
|
||||
|
||||
Reference in New Issue
Block a user