From 57e0309994be634f3935cf981d4b1ce60b481aba Mon Sep 17 00:00:00 2001 From: Max Audron Date: Tue, 9 Mar 2021 17:18:22 +0100 Subject: WIP: impl signalproxy types --- derive/src/from_network_impl.rs | 4 +-- derive/src/lib.rs | 78 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 77 insertions(+), 5 deletions(-) (limited to 'derive') 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) -> Vec { 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) -> Vec { } } 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, +} + +#[derive(Debug, FromVariant)] +#[darling(attributes(from))] +struct EnumField { + ident: syn::Ident, + fields: darling::ast::Fields, + + #[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 = 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() +} -- cgit v1.2.3