diff --git a/module/core/former_meta/Cargo.toml b/module/core/former_meta/Cargo.toml index d5b80364a1..87f531a9f9 100644 --- a/module/core/former_meta/Cargo.toml +++ b/module/core/former_meta/Cargo.toml @@ -46,7 +46,7 @@ full = [ ] enabled = [ "macro_tools/enabled", "iter_tools/enabled" ] -derive_former = [] +derive_former = [ "convert_case" ] derive_components = [] derive_component_assign = [] derive_components_assign = [ "derive_components", "derive_component_assign", "convert_case" ] diff --git a/module/core/former_meta/src/derive/former.rs b/module/core/former_meta/src/derive/former.rs index c75631b19c..8a816eb9bc 100644 --- a/module/core/former_meta/src/derive/former.rs +++ b/module/core/former_meta/src/derive/former.rs @@ -617,42 +617,53 @@ fn fields_setter_callback_descriptor_map -> Result< TokenStream > { - let ident = &field.ident; if field.attrs.subformer.is_none() { return Ok( qt!{ } ); } + use convert_case::{ Case, Casing }; + + let ident = field.ident; + let field_descriptor_name = format!( "former{}End", ident.to_string().to_case( Case::Camel ) ); + let field_descriptor = syn::Ident::new( &field_descriptor_name, ident.span() ); + + let field_ty = field.non_optional_ty; + // let xxx = field_ty; + // let generics = field_ty.generics + // let ( generics_impl, generics_ty, generics_where ) = generics.split_for_impl(); + let r = qt! { - xxx + // xxx // zzz : description /// Return original former after subformer for `vec_1` is done. #[ allow( non_camel_case_types ) ] - pub struct Struct1FormerVec_1End; + pub struct #field_descriptor; #[ automatically_derived ] impl< Definition > former::FormingEnd < - former::VectorDefinition< String, Struct1Former< Definition >, Struct1Former< Definition >, former::NoEnd >, + former::VectorDefinition< String, #former< Definition >, #former< Definition >, former::NoEnd >, > - for Struct1FormerVec_1End + for #field_descriptor where Definition : former::FormerDefinition, Definition::Types : former::FormerDefinitionTypes < - Storage = Struct1FormerStorage + Storage = #former_storage >, { #[ inline( always ) ] fn call ( - &self, storage : Vec< String >, - super_former : Option< Struct1Former< Definition > >, + &self, + storage : field_ty, + super_former : Option< #former< Definition > >, ) - -> Struct1Former< Definition > + -> #former< Definition > { let mut super_former = super_former.unwrap(); if let Some( ref mut field ) = super_former.storage.vec_1 diff --git a/module/core/macro_tools/src/generics.rs b/module/core/macro_tools/src/generics.rs index 63f8496495..05810d7943 100644 --- a/module/core/macro_tools/src/generics.rs +++ b/module/core/macro_tools/src/generics.rs @@ -183,6 +183,23 @@ pub( crate ) mod private result } + /// Extract generics from a type. + pub fn extract_from_type( type_example : &syn::Type ) -> Option< syn::PathArguments > + { + if let syn::Type::Path( type_path ) = type_example + { + let segments = &type_path.path.segments; + let last_segment = segments.last()?; + + if let syn::PathArguments::AngleBracketed( generics ) = &last_segment.arguments + { + return Some( generics.clone() ); + } + } + None + } + + } #[ doc( inline ) ] @@ -197,10 +214,12 @@ pub mod protected pub use super::orphan::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::private::merge; - #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::private::params_names; + pub use super::private:: + { + merge, + params_names, + extract_from_type, + }; } /// Orphan namespace of the module.