From 9c25ce7b02a705f4ef354ce85e053d74991c65b9 Mon Sep 17 00:00:00 2001 From: wandalen Date: Thu, 2 May 2024 18:24:49 +0300 Subject: [PATCH] former : experimenting --- .../examples/former_custom_subformer.rs | 3 + .../subformer_container_children2.rs | 21 +++++++ .../only_test/subformer_scalar_children.rs | 23 ++++++++ ..._subform.rs => subformer_subform_child.rs} | 0 .../only_test/subformer_subform_children2.rs | 19 ++++++ .../subformer_container_setter_off.rs | 21 +------ .../subformer_container_setter_on.rs | 45 +------------- .../inc/former_tests/subformer_subform.rs | 2 +- .../subformer_subform_and_container.rs | 4 +- ...rmer_subform_and_container_parametrized.rs | 2 +- .../former_tests/subformer_subform_hashmap.rs | 2 + .../former_tests/subformer_subform_manual.rs | 2 +- .../former_tests/subformer_subform_named.rs | 2 +- .../subformer_subform_named_manual.rs | 2 +- .../subformer_subform_setter_off.rs | 19 +----- .../subformer_subform_setter_on.rs | 43 +------------- module/core/former/tests/inc/mod.rs | 12 ++-- module/core/former_meta/src/derive/former.rs | 59 +++++++------------ 18 files changed, 107 insertions(+), 174 deletions(-) create mode 100644 module/core/former/tests/inc/former_tests/only_test/subformer_container_children2.rs create mode 100644 module/core/former/tests/inc/former_tests/only_test/subformer_scalar_children.rs rename module/core/former/tests/inc/former_tests/only_test/{subformer_subform.rs => subformer_subform_child.rs} (100%) create mode 100644 module/core/former/tests/inc/former_tests/only_test/subformer_subform_children2.rs diff --git a/module/core/former/examples/former_custom_subformer.rs b/module/core/former/examples/former_custom_subformer.rs index 426e61253d..9240a7f85d 100644 --- a/module/core/former/examples/former_custom_subformer.rs +++ b/module/core/former/examples/former_custom_subformer.rs @@ -96,3 +96,6 @@ fn main() // > }, // > } } + +// xxx2 : finish example former_custom_subformer + diff --git a/module/core/former/tests/inc/former_tests/only_test/subformer_container_children2.rs b/module/core/former/tests/inc/former_tests/only_test/subformer_container_children2.rs new file mode 100644 index 0000000000..44aac2d08f --- /dev/null +++ b/module/core/former/tests/inc/former_tests/only_test/subformer_container_children2.rs @@ -0,0 +1,21 @@ + +#[ test ] +fn container() +{ + + let got = Parent::former() + .children2() + .add( Child::former().name( "a" ).form() ) + .add( Child::former().name( "b" ).form() ) + .end() + .form(); + + let children = vec! + [ + Child { name : "a".to_string(), is_mandatory : false }, + Child { name : "b".to_string(), is_mandatory : false }, + ]; + let exp = Parent { children }; + a_id!( got, exp ); + +} diff --git a/module/core/former/tests/inc/former_tests/only_test/subformer_scalar_children.rs b/module/core/former/tests/inc/former_tests/only_test/subformer_scalar_children.rs new file mode 100644 index 0000000000..18a16fc71c --- /dev/null +++ b/module/core/former/tests/inc/former_tests/only_test/subformer_scalar_children.rs @@ -0,0 +1,23 @@ + +#[ test ] +fn scalar() +{ + + let children = vec! + [ + Child { name : "a".to_string(), is_mandatory : false }, + Child { name : "b".to_string(), is_mandatory : false }, + ]; + let got = Parent::former() + .children( children ) + .form(); + + let children = vec! + [ + Child { name : "a".to_string(), is_mandatory : false }, + Child { name : "b".to_string(), is_mandatory : false }, + ]; + let exp = Parent { children }; + a_id!( got, exp ); + +} diff --git a/module/core/former/tests/inc/former_tests/only_test/subformer_subform.rs b/module/core/former/tests/inc/former_tests/only_test/subformer_subform_child.rs similarity index 100% rename from module/core/former/tests/inc/former_tests/only_test/subformer_subform.rs rename to module/core/former/tests/inc/former_tests/only_test/subformer_subform_child.rs diff --git a/module/core/former/tests/inc/former_tests/only_test/subformer_subform_children2.rs b/module/core/former/tests/inc/former_tests/only_test/subformer_subform_children2.rs new file mode 100644 index 0000000000..0fac0895c5 --- /dev/null +++ b/module/core/former/tests/inc/former_tests/only_test/subformer_subform_children2.rs @@ -0,0 +1,19 @@ + +#[ test ] +fn subform() +{ + + let got = Parent::former() + .children2( "a" ).end() + .children2( "b" ).end() + .form(); + + let children = vec! + [ + Child { name : "a".to_string(), is_mandatory : false }, + Child { name : "b".to_string(), is_mandatory : false }, + ]; + let exp = Parent { children }; + a_id!( got, exp ); + +} diff --git a/module/core/former/tests/inc/former_tests/subformer_container_setter_off.rs b/module/core/former/tests/inc/former_tests/subformer_container_setter_off.rs index b20fe7e374..d30ddb2743 100644 --- a/module/core/former/tests/inc/former_tests/subformer_container_setter_off.rs +++ b/module/core/former/tests/inc/former_tests/subformer_container_setter_off.rs @@ -49,23 +49,4 @@ where } -#[ test ] -fn container() -{ - - let got = Parent::former() - .children2() - .add( Child::former().name( "a" ).form() ) - .add( Child::former().name( "b" ).form() ) - .end() - .form(); - - let children = vec! - [ - Child { name : "a".to_string(), is_mandatory : false }, - Child { name : "b".to_string(), is_mandatory : false }, - ]; - let exp = Parent { children }; - a_id!( got, exp ); - -} +include!( "./only_test/subformer_container_children2.rs" ); diff --git a/module/core/former/tests/inc/former_tests/subformer_container_setter_on.rs b/module/core/former/tests/inc/former_tests/subformer_container_setter_on.rs index f8d963a732..b4bd686094 100644 --- a/module/core/former/tests/inc/former_tests/subformer_container_setter_on.rs +++ b/module/core/former/tests/inc/former_tests/subformer_container_setter_on.rs @@ -41,46 +41,5 @@ where } -#[ test ] -fn scalar() -{ - - let children = vec! - [ - Child { name : "a".to_string(), is_mandatory : false }, - Child { name : "b".to_string(), is_mandatory : false }, - ]; - let got = Parent::former() - .children( children ) - .form(); - - let children = vec! - [ - Child { name : "a".to_string(), is_mandatory : false }, - Child { name : "b".to_string(), is_mandatory : false }, - ]; - let exp = Parent { children }; - a_id!( got, exp ); - -} - -#[ test ] -fn container() -{ - - let got = Parent::former() - .children2() - .add( Child::former().name( "a" ).form() ) - .add( Child::former().name( "b" ).form() ) - .end() - .form(); - - let children = vec! - [ - Child { name : "a".to_string(), is_mandatory : false }, - Child { name : "b".to_string(), is_mandatory : false }, - ]; - let exp = Parent { children }; - a_id!( got, exp ); - -} +include!( "./only_test/subformer_scalar_children.rs" ); +include!( "./only_test/subformer_container_children2.rs" ); diff --git a/module/core/former/tests/inc/former_tests/subformer_subform.rs b/module/core/former/tests/inc/former_tests/subformer_subform.rs index 7781e87b37..9d9112f406 100644 --- a/module/core/former/tests/inc/former_tests/subformer_subform.rs +++ b/module/core/former/tests/inc/former_tests/subformer_subform.rs @@ -46,4 +46,4 @@ where // == end of generated -include!( "./only_test/subformer_subform.rs" ); +include!( "./only_test/subformer_subform_child.rs" ); diff --git a/module/core/former/tests/inc/former_tests/subformer_subform_and_container.rs b/module/core/former/tests/inc/former_tests/subformer_subform_and_container.rs index a43809dff4..c3599a76c3 100644 --- a/module/core/former/tests/inc/former_tests/subformer_subform_and_container.rs +++ b/module/core/former/tests/inc/former_tests/subformer_subform_and_container.rs @@ -18,7 +18,7 @@ pub struct Parent { // #[ subform ] #[ subform( name = _child ) ] - #[ container( former::VectorDefinition ) ] + #[ container( definition = former::VectorDefinition ) ] // #[ scalar_setter( false ) ] children : Vec< Child >, } @@ -44,5 +44,5 @@ where // == end of generated -include!( "./only_test/subformer_subform.rs" ); +include!( "./only_test/subformer_subform_child.rs" ); include!( "./only_test/subformer_container.rs" ); diff --git a/module/core/former/tests/inc/former_tests/subformer_subform_and_container_parametrized.rs b/module/core/former/tests/inc/former_tests/subformer_subform_and_container_parametrized.rs index 1631921866..1771eedcc4 100644 --- a/module/core/former/tests/inc/former_tests/subformer_subform_and_container_parametrized.rs +++ b/module/core/former/tests/inc/former_tests/subformer_subform_and_container_parametrized.rs @@ -47,5 +47,5 @@ pub struct Child< 'child, T > // == end of generated -// include!( "./only_test/subformer_subform.rs" ); +// include!( "./only_test/subformer_subform_child.rs" ); // include!( "./only_test/subformer_container.rs" ); diff --git a/module/core/former/tests/inc/former_tests/subformer_subform_hashmap.rs b/module/core/former/tests/inc/former_tests/subformer_subform_hashmap.rs index a6d3afe3c9..4f9c0e50f1 100644 --- a/module/core/former/tests/inc/former_tests/subformer_subform_hashmap.rs +++ b/module/core/former/tests/inc/former_tests/subformer_subform_hashmap.rs @@ -55,3 +55,5 @@ fn basic() a_id!( got.command.len(), 2 ); } + +// xxx2 : finish example former_custom_subformer diff --git a/module/core/former/tests/inc/former_tests/subformer_subform_manual.rs b/module/core/former/tests/inc/former_tests/subformer_subform_manual.rs index a9fd5299f8..c26a4cf083 100644 --- a/module/core/former/tests/inc/former_tests/subformer_subform_manual.rs +++ b/module/core/former/tests/inc/former_tests/subformer_subform_manual.rs @@ -192,4 +192,4 @@ where // == end of generated for Parent in context of attribute subform -include!( "./only_test/subformer_subform.rs" ); +include!( "./only_test/subformer_subform_child.rs" ); diff --git a/module/core/former/tests/inc/former_tests/subformer_subform_named.rs b/module/core/former/tests/inc/former_tests/subformer_subform_named.rs index db036526a5..4e56df7523 100644 --- a/module/core/former/tests/inc/former_tests/subformer_subform_named.rs +++ b/module/core/former/tests/inc/former_tests/subformer_subform_named.rs @@ -51,4 +51,4 @@ where // == end of generated -include!( "./only_test/subformer_subform.rs" ); +include!( "./only_test/subformer_subform_child.rs" ); diff --git a/module/core/former/tests/inc/former_tests/subformer_subform_named_manual.rs b/module/core/former/tests/inc/former_tests/subformer_subform_named_manual.rs index 4c04066614..91745540ba 100644 --- a/module/core/former/tests/inc/former_tests/subformer_subform_named_manual.rs +++ b/module/core/former/tests/inc/former_tests/subformer_subform_named_manual.rs @@ -77,4 +77,4 @@ where // == end of generated for Parent in context of attribute subform -include!( "./only_test/subformer_subform.rs" ); +include!( "./only_test/subformer_subform_child.rs" ); diff --git a/module/core/former/tests/inc/former_tests/subformer_subform_setter_off.rs b/module/core/former/tests/inc/former_tests/subformer_subform_setter_off.rs index a467fd2bea..95dabce287 100644 --- a/module/core/former/tests/inc/former_tests/subformer_subform_setter_off.rs +++ b/module/core/former/tests/inc/former_tests/subformer_subform_setter_off.rs @@ -49,21 +49,4 @@ where } -#[ test ] -fn subform() -{ - - let got = Parent::former() - .children2( "a" ).end() - .children2( "b" ).end() - .form(); - - let children = vec! - [ - Child { name : "a".to_string(), is_mandatory : false }, - Child { name : "b".to_string(), is_mandatory : false }, - ]; - let exp = Parent { children }; - a_id!( got, exp ); - -} +include!( "./only_test/subformer_subform_children2.rs" ); diff --git a/module/core/former/tests/inc/former_tests/subformer_subform_setter_on.rs b/module/core/former/tests/inc/former_tests/subformer_subform_setter_on.rs index 2630abc97b..1c8883f544 100644 --- a/module/core/former/tests/inc/former_tests/subformer_subform_setter_on.rs +++ b/module/core/former/tests/inc/former_tests/subformer_subform_setter_on.rs @@ -40,44 +40,5 @@ where } -#[ test ] -fn scalar() -{ - - let children = vec! - [ - Child { name : "a".to_string(), is_mandatory : false }, - Child { name : "b".to_string(), is_mandatory : false }, - ]; - let got = Parent::former() - .children( children ) - .form(); - - let children = vec! - [ - Child { name : "a".to_string(), is_mandatory : false }, - Child { name : "b".to_string(), is_mandatory : false }, - ]; - let exp = Parent { children }; - a_id!( got, exp ); - -} - -#[ test ] -fn subform() -{ - - let got = Parent::former() - .children2( "a" ).end() - .children2( "b" ).end() - .form(); - - let children = vec! - [ - Child { name : "a".to_string(), is_mandatory : false }, - Child { name : "b".to_string(), is_mandatory : false }, - ]; - let exp = Parent { children }; - a_id!( got, exp ); - -} +include!( "./only_test/subformer_scalar_children.rs" ); +include!( "./only_test/subformer_subform_children2.rs" ); diff --git a/module/core/former/tests/inc/mod.rs b/module/core/former/tests/inc/mod.rs index 8a4cf017f1..00ce81a4f4 100644 --- a/module/core/former/tests/inc/mod.rs +++ b/module/core/former/tests/inc/mod.rs @@ -83,12 +83,12 @@ mod former_tests #[ cfg( any( not( feature = "no_std" ) ) ) ] mod subformer_subform_setter_on; -// #[ cfg( any( not( feature = "no_std" ) ) ) ] -// mod subformer_subform_hashmap; -// #[ cfg( any( not( feature = "no_std" ) ) ) ] -// mod subformer_subform_hashmap_explicit; - // #[ cfg( any( not( feature = "no_std" ) ) ) ] - // mod subformer_subform_and_container; + #[ cfg( any( not( feature = "no_std" ) ) ) ] + mod subformer_subform_hashmap; + #[ cfg( any( not( feature = "no_std" ) ) ) ] + mod subformer_subform_hashmap_explicit; + #[ cfg( any( not( feature = "no_std" ) ) ) ] + mod subformer_subform_and_container; // #[ cfg( any( not( feature = "no_std" ) ) ) ] // mod subformer_subform_and_container_parametrized; diff --git a/module/core/former_meta/src/derive/former.rs b/module/core/former_meta/src/derive/former.rs index 37be332632..7eaee92404 100644 --- a/module/core/former_meta/src/derive/former.rs +++ b/module/core/former_meta/src/derive/former.rs @@ -292,15 +292,19 @@ impl syn::parse::Parse for AttributeScalarSetter } } +/// Represents an attribute for configuring setter generation in container-like structures. /// -/// Attribute to enable/disable/customize container setter generation. +/// This struct is part of a meta-programming approach to enable detailed configuration of nested structs or collections such as `Vec< E >, HashMap< K, E >` and so on. +/// It allows the customization of setter methods and the specification of the container's behavior through meta attributes. /// -/// Also known as subformers, used for aggregation relationship, when a struct holds another struct, which needs to be build by invoking multiple methods -/// Typical example is a struct holding a `Vec` +/// ## Example Input /// -/// `#[ container( former::VectorSubformer ) ]` +/// The following is an example of a token stream that this struct can parse: +/// ```ignore +/// container( name = "custom_setter", setter = true, definition = former::VectorDefinition ) +/// ``` +/// This example configures a struct to use a custom setter named `custom_setter` and enables setter generation using `former::VectorDefinition` as definition of the container former. /// -// qqq : update documentation struct AttributeContainer { @@ -309,7 +313,7 @@ struct AttributeContainer /// Controls the generation of a setter method. If false, a setter method is not generated. setter : Option< bool >, /// Definition of the container former to use, e.g., `former::VectorSubformer`. - expr : Option< syn::Type >, + definition : Option< syn::Type >, } impl syn::parse::Parse for AttributeContainer @@ -318,7 +322,7 @@ impl syn::parse::Parse for AttributeContainer { let mut name : Option< syn::Ident > = None; let mut setter : Option< bool > = None; // Default is to generate a setter - let mut expr : Option< syn::Type > = None; + let mut definition : Option< syn::Type > = None; while !input.is_empty() { @@ -340,16 +344,19 @@ impl syn::parse::Parse for AttributeContainer else if ident == "definition" { input.parse::< syn::Token![ = ] >()?; - expr = Some( input.parse()? ); + definition = Some( input.parse()? ); } else { - return Err( lookahead.error() ); + return Err( syn::Error::new_spanned( &ident, format!( "Unexpected identifier '{}'. Expected 'name', 'setter', or 'definition'. For example: name = myName, setter = true, definition = MyContainerType", ident ) ) ); + // return Err( lookahead.error() ); } } else { - return Err( lookahead.error() ); + // return Err( lookahead.error() ); + // return Err( lookahead.error_with( "Expected 'name', 'setter', or 'definition' identifier " ) ); + return Err( syn::Error::new( input.span(), "Expected 'name', 'setter', or 'definition' identifier" ) ); } // Optional comma handling @@ -359,36 +366,10 @@ impl syn::parse::Parse for AttributeContainer } } - Ok( Self { name, setter, expr } ) + Ok( Self { name, setter, definition } ) } } -// -// struct AttributeContainer -// { -// // /// An optional identifier that names the setter. It is parsed from inputs -// // /// like `name = my_field`. -// // name : Option< syn::Ident >, -// // /// Disable generation of setter. -// // /// It still generate `_field_add` method, so it could be used to make a setter with custom arguments. -// // setter : bool, -// /// Definition of container former to use. -// /// Look [`former::ContainerSubformer`] and [`former::VectorDefinition`]. -// expr : Option< syn::Type >, // xxx : rename -// } -// -// impl syn::parse::Parse for AttributeContainer -// { -// fn parse( input : syn::parse::ParseStream< '_ > ) -> Result< Self > -// { -// let expr : Option< syn::Type > = input.parse().ok(); -// Ok( Self -// { -// expr, -// }) -// } -// } - /// Represents a subform attribute with optional name flag. /// Used to specify extra options for using one former as subformer of another one. /// For example name of setter could be customized. @@ -983,7 +964,7 @@ fn field_container_setter let field_assign = syn::Ident::new( &field_assign_name, field_ident.span() ); // example : `former::VectorDefinition` - let subformer_definition = &field.attrs.container.as_ref().unwrap().expr; + let subformer_definition = &field.attrs.container.as_ref().unwrap().definition; let subformer_definition = if subformer_definition.is_some() { qt! @@ -1238,7 +1219,7 @@ Result< TokenStream > let former_assign_end = syn::Ident::new( &former_assign_end_name, field_ident.span() ); // example : `former::VectorDefinition`` - let subformer_definition = &field.attrs.container.as_ref().unwrap().expr; + let subformer_definition = &field.attrs.container.as_ref().unwrap().definition; // zzz : improve description let former_assign_end_doc = format!