diff options
| author | Max Audron <audron@cocaine.farm> | 2021-03-09 17:18:22 +0100 |
|---|---|---|
| committer | Max Audron <audron@cocaine.farm> | 2021-03-09 17:18:22 +0100 |
| commit | 57e0309994be634f3935cf981d4b1ce60b481aba (patch) | |
| tree | b6a5f9cfc28e6aa7ce4e6b9bbc41faa76003984e /derive | |
| parent | add to and from network derive (diff) | |
WIP: impl signalproxy types
Diffstat (limited to 'derive')
| -rw-r--r-- | derive/src/from_network_impl.rs | 4 | ||||
| -rw-r--r-- | derive/src/lib.rs | 78 |
2 files changed, 77 insertions, 5 deletions
diff --git a/derive/src/from_network_impl.rs b/derive/src/from_network_impl.rs index c3a3be2..ff05f1c 100644 --- a/derive/src/from_network_impl.rs +++ b/derive/src/from_network_impl.rs @@ -56,7 +56,7 @@ pub(crate) fn map_list(fields: &Vec<NetworkField>) -> Vec<TokenStream> { syn::parse_str(&field.from_map.as_ref().unwrap()).unwrap(); quote! { - #field_name: match input.get(#field_rename).unwrap() { + #field_name: match input.get_mut(#field_rename).unwrap() { crate::primitive::Variant::VariantList(input) => match &input.remove(0) { crate::primitive::Variant::#field_type(input) => input.iter().map(#field_map).collect(), _ => unimplemented!() @@ -66,7 +66,7 @@ pub(crate) fn map_list(fields: &Vec<NetworkField>) -> Vec<TokenStream> { } } else { quote! { - #field_name: match input.get(#field_rename).unwrap() { + #field_name: match input.get_mut(#field_rename).unwrap() { crate::primitive::Variant::VariantList(input) => match &input.remove(0) { crate::primitive::Variant::#field_type(input) => input.clone(), _ => unimplemented!() diff --git a/derive/src/lib.rs b/derive/src/lib.rs index 10605a4..ddbb49a 100644 --- a/derive/src/lib.rs +++ b/derive/src/lib.rs @@ -3,7 +3,7 @@ use syn; use syn::parse_macro_input; -use darling::{FromDeriveInput, FromField, FromMeta}; +use darling::{FromDeriveInput, FromField, FromMeta, FromVariant}; mod from_network_impl; mod to_network_impl; @@ -107,7 +107,7 @@ pub fn network(input: proc_macro::TokenStream) -> proc_macro::TokenStream { return res; } - fn from_network(input: Self::Item) -> Self { + fn from_network(input: &mut Self::Item) -> Self { Self { #(#from_network_impl_center)* } @@ -115,7 +115,7 @@ pub fn network(input: proc_macro::TokenStream) -> proc_macro::TokenStream { } }; - // println!("{}", gen); + println!("{}", gen); gen.into() } @@ -142,3 +142,75 @@ fn get_field_type(field: &NetworkField) -> syn::Type { None => field.ty.clone(), } } + +#[derive(Debug, FromDeriveInput)] +#[darling(attributes(from), supports(enum_any))] +struct Enum { + ident: syn::Ident, + attrs: Vec<syn::Attribute>, +} + +#[derive(Debug, FromVariant)] +#[darling(attributes(from))] +struct EnumField { + ident: syn::Ident, + fields: darling::ast::Fields<syn::Type>, + + #[darling(default)] + ignore: bool, +} + +#[proc_macro_derive(From, attributes(from))] +pub fn from(input: proc_macro::TokenStream) -> proc_macro::TokenStream { + let input = parse_macro_input!(input as syn::DeriveInput); + // println!("{:#?}", input); + + let network = Enum::from_derive_input(&input).unwrap(); + // println!("{:#?}", network); + + let enum_name = network.ident; + + let fields: Vec<EnumField> = match &input.data { + syn::Data::Enum(data) => data + .variants + .iter() + .map(|field| EnumField::from_variant(field).expect("Could not parse field")) + .collect(), + _ => unimplemented!(), + }; + + let derives = fields + .iter() + .filter(|field| field.fields.fields.len() > 0 && !field.ignore) + .map(|field| { + let variant = &field.ident; + let inner_type = &field.fields.fields[0]; + + quote! { + impl From<#inner_type> for #enum_name { + fn from(input: #inner_type) -> Self { + Self::#variant(input) + } + } + + impl Into<#inner_type> for #enum_name { + fn into(self) -> #inner_type { + match self { + Self::#variant(input) => input, + _ => unimplemented!(), + } + } + } + } + }); + + // println!("{:#?}", fields); + + let gen = quote! { + #(#derives)* + }; + + // println!("{}", gen); + + gen.into() +} |
