From 571e5a5cf95e13269a004e65540439c03a54548b Mon Sep 17 00:00:00 2001 From: wandalen Date: Mon, 27 May 2024 22:33:34 +0300 Subject: [PATCH 01/59] regenerate readme --- Readme.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index c77bc38422..d372d888da 100644 --- a/Readme.md +++ b/Readme.md @@ -22,9 +22,10 @@ Collection of general purpose tools for solving problems. Fundamentally extend t | [clone_dyn_meta](module/core/clone_dyn_meta) | [![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/module_clone_dyn_meta_push.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/module_clone_dyn_meta_push.yml?query=branch%3Amaster) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/module_clone_dyn_meta_push.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/module_clone_dyn_meta_push.yml?query=branch%3Aalpha) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/clone_dyn_meta) | | | [derive_tools_meta](module/core/derive_tools_meta) | [![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/module_derive_tools_meta_push.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/module_derive_tools_meta_push.yml?query=branch%3Amaster) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/module_derive_tools_meta_push.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/module_derive_tools_meta_push.yml?query=branch%3Aalpha) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/derive_tools_meta) | | | [clone_dyn](module/core/clone_dyn) | [![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/module_clone_dyn_push.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/module_clone_dyn_push.yml?query=branch%3Amaster) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/module_clone_dyn_push.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/module_clone_dyn_push.yml?query=branch%3Aalpha) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/clone_dyn) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=module%2Fcore%2Fclone_dyn%2Fexamples%2Fclone_dyn_trivial.rs,RUN_POSTFIX=--example%20clone_dyn_trivial/https://github.com/Wandalen/wTools) | +| [collection_tools](module/core/collection_tools) | [![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/module_collection_tools_push.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/module_collection_tools_push.yml?query=branch%3Amaster) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/module_collection_tools_push.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/module_collection_tools_push.yml?query=branch%3Aalpha) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/collection_tools) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=module%2Fcore%2Fcollection_tools%2Fexamples%2Fcollection_tools_trivial.rs,RUN_POSTFIX=--example%20collection_tools_trivial/https://github.com/Wandalen/wTools) | | [variadic_from](module/core/variadic_from) | [![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/module_variadic_from_push.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/module_variadic_from_push.yml?query=branch%3Amaster) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/module_variadic_from_push.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/module_variadic_from_push.yml?query=branch%3Aalpha) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/variadic_from) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=module%2Fcore%2Fvariadic_from%2Fexamples%2Fvariadic_from_trivial.rs,RUN_POSTFIX=--example%20variadic_from_trivial/https://github.com/Wandalen/wTools) | | [derive_tools](module/core/derive_tools) | [![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/module_derive_tools_push.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/module_derive_tools_push.yml?query=branch%3Amaster) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/module_derive_tools_push.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/module_derive_tools_push.yml?query=branch%3Aalpha) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/derive_tools) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=module%2Fcore%2Fderive_tools%2Fexamples%2Fderive_tools_trivial.rs,RUN_POSTFIX=--example%20derive_tools_trivial/https://github.com/Wandalen/wTools) | -| [collection_tools](module/core/collection_tools) | [![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/module_collection_tools_push.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/module_collection_tools_push.yml?query=branch%3Amaster) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/module_collection_tools_push.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/module_collection_tools_push.yml?query=branch%3Aalpha) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/collection_tools) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=module%2Fcore%2Fcollection_tools%2Fexamples%2Fcollection_tools_trivial.rs,RUN_POSTFIX=--example%20collection_tools_trivial/https://github.com/Wandalen/wTools) | +| [former_types](module/core/former_types) | [![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/module_former_types_push.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/module_former_types_push.yml?query=branch%3Amaster) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/module_former_types_push.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/module_former_types_push.yml?query=branch%3Aalpha) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/former_types) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=module%2Fcore%2Fformer_types%2Fexamples%2Fformer_types_trivial.rs,RUN_POSTFIX=--example%20former_types_trivial/https://github.com/Wandalen/wTools) | | [former_meta](module/core/former_meta) | [![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/module_former_meta_push.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/module_former_meta_push.yml?query=branch%3Amaster) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/module_former_meta_push.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/module_former_meta_push.yml?query=branch%3Aalpha) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/former_meta) | | | [impls_index_meta](module/core/impls_index_meta) | [![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/module_impls_index_meta_push.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/module_impls_index_meta_push.yml?query=branch%3Amaster) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/module_impls_index_meta_push.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/module_impls_index_meta_push.yml?query=branch%3Aalpha) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/impls_index_meta) | | | [mod_interface_meta](module/core/mod_interface_meta) | [![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/module_mod_interface_meta_push.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/module_mod_interface_meta_push.yml?query=branch%3Amaster) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/module_mod_interface_meta_push.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/module_mod_interface_meta_push.yml?query=branch%3Aalpha) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/mod_interface_meta) | | From 55609bb6340c1d74c38102f32ea2509fbf994bb1 Mon Sep 17 00:00:00 2001 From: wandalen Date: Tue, 28 May 2024 00:24:37 +0300 Subject: [PATCH 02/59] macro_tools : attr_props example --- module/core/former_meta/Cargo.toml | 2 +- .../src/derive_former/struct_attrs.rs | 2 + module/core/former_types/src/lib.rs | 2 +- module/core/macro_tools/Cargo.toml | 2 + module/core/macro_tools/src/attr_prop.rs | 7 +- .../tests/inc/attr_prop_example.rs | 273 ++++++++++++++++++ .../macro_tools/tests/inc/attr_prop_test.rs | 3 +- module/core/macro_tools/tests/inc/mod.rs | 1 + 8 files changed, 286 insertions(+), 6 deletions(-) create mode 100644 module/core/macro_tools/tests/inc/attr_prop_example.rs diff --git a/module/core/former_meta/Cargo.toml b/module/core/former_meta/Cargo.toml index 770817a07f..1ebe5ba608 100644 --- a/module/core/former_meta/Cargo.toml +++ b/module/core/former_meta/Cargo.toml @@ -58,7 +58,7 @@ proc-macro = true [dependencies] macro_tools = { workspace = true } # qqq : optimize set of features -former_types = { workspace = true, features = [ "types_component_assign" ] } # qqq : optimize set of features +former_types = { workspace = true, features = [ "types_component_assign" ] } iter_tools = { workspace = true } convert_case = { version = "0.6.0", default-features = false, optional = true, features = [] } const_format = { version = "0.2.32" } diff --git a/module/core/former_meta/src/derive_former/struct_attrs.rs b/module/core/former_meta/src/derive_former/struct_attrs.rs index 73e11f9cb0..a06bc9b275 100644 --- a/module/core/former_meta/src/derive_former/struct_attrs.rs +++ b/module/core/former_meta/src/derive_former/struct_attrs.rs @@ -1,4 +1,6 @@ +//! //! Attributes of the whole item. +//! use super::*; diff --git a/module/core/former_types/src/lib.rs b/module/core/former_types/src/lib.rs index 90b2af5410..51cfc78eab 100644 --- a/module/core/former_types/src/lib.rs +++ b/module/core/former_types/src/lib.rs @@ -8,7 +8,7 @@ #[ cfg( feature = "enabled" ) ] #[ cfg( feature = "derive_former" ) ] mod axiomatic; -/// Forming process. +/// Definition of former. #[ cfg( feature = "enabled" ) ] #[ cfg( feature = "derive_former" ) ] mod definition; diff --git a/module/core/macro_tools/Cargo.toml b/module/core/macro_tools/Cargo.toml index 75b5cd11fd..b01417bfad 100644 --- a/module/core/macro_tools/Cargo.toml +++ b/module/core/macro_tools/Cargo.toml @@ -45,3 +45,5 @@ interval_adapter = { workspace = true, features = [ "default" ] } [dev-dependencies] test_tools = { workspace = true } +former_types = { workspace = true, features = [ "enabled", "types_component_assign" ] } +const_format = { version = "0.2.32" } diff --git a/module/core/macro_tools/src/attr_prop.rs b/module/core/macro_tools/src/attr_prop.rs index 0193a8653a..711afe225c 100644 --- a/module/core/macro_tools/src/attr_prop.rs +++ b/module/core/macro_tools/src/attr_prop.rs @@ -1,7 +1,6 @@ //! //! Attribute's properties. Reuse them to define how to parse properties of an attribute. //! -//! //! # Example //! //! ```rust @@ -97,8 +96,6 @@ //! The `parse_quote!` macro is used to create a `syn::Attribute` instance with the attribute syntax, //! which is then parsed into the `MyAttributes` struct. The resulting `MyAttributes` instance is printed to the console. -// xxx : qqq : improve documentation, add examples - /// Internal namespace. pub( crate ) mod private { @@ -362,7 +359,9 @@ pub( crate ) mod private // = AttributePropertySyn + /// /// Property of an attribute which simply wraps one of the standard `syn` types. + /// #[ derive( Debug, Clone ) ] pub struct AttributePropertySyn< T, Marker >( T, ::core::marker::PhantomData< Marker > ) where @@ -449,7 +448,9 @@ pub( crate ) mod private // = AttributePropertyOptionalSyn + /// /// Property of an attribute which simply wraps one of the standard `syn` types and keeps it optional. + /// #[ derive( Debug, Clone ) ] pub struct AttributePropertyOptionalSyn< T, Marker >( Option< T >, ::core::marker::PhantomData< Marker > ) where diff --git a/module/core/macro_tools/tests/inc/attr_prop_example.rs b/module/core/macro_tools/tests/inc/attr_prop_example.rs new file mode 100644 index 0000000000..85c260721f --- /dev/null +++ b/module/core/macro_tools/tests/inc/attr_prop_example.rs @@ -0,0 +1,273 @@ +// use super::*; +// use quote::ToTokens; + +#[ test ] +fn attr_props_draft() +{ + + use macro_tools:: + { + attr, + syn_err, + return_syn_err, + qt, + Result, + AttributeComponent, + AttributePropertyComponent, + AttributePropertyBoolean, + }; + + use former_types::{ ComponentAssign }; + + /// Represents the attributes of a struct. Aggregates all its attributes. + #[ derive( Debug, Default ) ] + pub struct StructAttributes + { + /// Attribute for customizing the mutation process. + pub mutator : AttributeMutator, + } + + impl StructAttributes + { + + pub fn from_attrs< 'a >( attrs : impl Iterator< Item = &'a syn::Attribute > ) -> Result< Self > + { + let mut result = Self::default(); + + let error = | attr : &syn::Attribute | -> syn::Error + { + let known_attributes = const_format::concatcp! + ( + "Known attirbutes are : ", + "debug", + ", ", AttributeMutator::KEYWORD, + ".", + ); + syn_err! + ( + attr, + "Expects an attribute of format '#[ attribute( key1 = val1, key2 = val2 ) ]'\n {known_attributes}\n But got: '{}'", + qt!{ #attr } + ) + }; + + for attr in attrs + { + + let key_ident = attr.path().get_ident().ok_or_else( || error( attr ) )?; + let key_str = format!( "{}", key_ident ); + + if attr::is_standard( &key_str ) + { + continue; + } + + match key_str.as_ref() + { + AttributeMutator::KEYWORD => result.assign( AttributeMutator::from_meta( attr )? ), + "debug" => {} + _ => return Err( error( attr ) ), + } + } + + Ok( result ) + } + + } + + /// Represents attributes for customizing the mutation process in a forming operation. + /// + /// ## Example of code + /// + /// ```ignore + /// #[ mutator( custom = true, hint = true ) ] + /// ``` + + #[ derive( Debug, Default ) ] + pub struct AttributeMutator + { + /// Indicates whether a custom mutator should be generated. + /// Defaults to `false`, meaning no custom mutator is generated unless explicitly requested. + pub custom : AttributePropertyCustom, + /// Specifies whether to provide a sketch of the mutator as a hint. + /// Defaults to `false`, which means no hint is provided unless explicitly requested. + pub hint : AttributePropertyHint, + } + + impl AttributeComponent for AttributeMutator + { + const KEYWORD : &'static str = "mutator"; + + fn from_meta( attr : &syn::Attribute ) -> Result< Self > + { + match attr.meta + { + syn::Meta::List( ref meta_list ) => + { + return syn::parse2::< AttributeMutator >( meta_list.tokens.clone() ); + }, + syn::Meta::Path( ref _path ) => + { + return Ok( Default::default() ) + }, + _ => return_syn_err!( attr, "Expects an attribute of format `#[ mutator( custom = true, hint = true ) ]`. \nGot: {}", qt!{ #attr } ), + } + } + + } + + impl< IntoT > ComponentAssign< AttributeMutator, IntoT > for StructAttributes + where + IntoT : Into< AttributeMutator >, + { + #[ inline( always ) ] + fn assign( &mut self, component : IntoT ) + { + self.mutator = component.into(); + } + } + + impl< IntoT > ComponentAssign< AttributePropertyHint, IntoT > for AttributeMutator + where + IntoT : Into< AttributePropertyHint >, + { + #[ inline( always ) ] + fn assign( &mut self, component : IntoT ) + { + self.hint = component.into(); + } + } + + impl< IntoT > ComponentAssign< AttributePropertyCustom, IntoT > for AttributeMutator + where + IntoT : Into< AttributePropertyCustom >, + { + #[ inline( always ) ] + fn assign( &mut self, component : IntoT ) + { + self.custom = component.into(); + } + } + + impl syn::parse::Parse for AttributeMutator + { + fn parse( input : syn::parse::ParseStream< '_ > ) -> syn::Result< Self > + { + let mut result = Self::default(); + + let error = | ident : &syn::Ident | -> syn::Error + { + let known = const_format::concatcp! + ( + "Known entries of attribute ", AttributeMutator::KEYWORD, " are : ", + AttributePropertyCustom::KEYWORD, + ", ", AttributePropertyHint::KEYWORD, + ".", + ); + syn_err! + ( + ident, + r#"Expects an attribute of format '#[ mutator( custom = false, hint = false ) ]' + {known} + But got: '{}' + "#, + qt!{ #ident } + ) + }; + + while !input.is_empty() + { + let lookahead = input.lookahead1(); + if lookahead.peek( syn::Ident ) + { + let ident : syn::Ident = input.parse()?; + + input.parse::< syn::Token![=] >()?; + match ident.to_string().as_str() + { + AttributePropertyCustom::KEYWORD => result.assign( AttributePropertyCustom::parse( input )? ), + AttributePropertyHint::KEYWORD => result.assign( AttributePropertyHint::parse( input )? ), + _ => return Err( error( &ident ) ), + } + } + else + { + return Err( lookahead.error() ); + } + + // Optional comma handling + if input.peek( syn::Token![ , ] ) + { + input.parse::< syn::Token![ , ] >()?; + } + } + + Ok( result ) + } + } + + // == attribute properties + + /// Marker type for attribute property to specify whether to provide a sketch as a hint. + /// Defaults to `false`, which means no hint is provided unless explicitly requested. + #[ derive( Debug, Default, Clone, Copy ) ] + pub struct AttributePropertyHintMarker; + + impl AttributePropertyComponent for AttributePropertyHintMarker + { + const KEYWORD : &'static str = "hint"; + } + + /// Specifies whether to provide a sketch as a hint. + /// Defaults to `false`, which means no hint is provided unless explicitly requested. + pub type AttributePropertyHint = AttributePropertyBoolean< AttributePropertyHintMarker >; + + // = + + /// Marker type for attribute property to indicates whether a custom code should be generated. + /// Defaults to `false`, meaning no custom code is generated unless explicitly requested. + #[ derive( Debug, Default, Clone, Copy ) ] + pub struct AttributePropertyCustomMarker; + + impl AttributePropertyComponent for AttributePropertyCustomMarker + { + const KEYWORD : &'static str = "custom"; + } + + /// Indicates whether a custom code should be generated. + /// Defaults to `false`, meaning no custom code is generated unless explicitly requested. + pub type AttributePropertyCustom = AttributePropertyBoolean< AttributePropertyCustomMarker >; + + // == Test code + + let input : syn::Attribute = syn::parse_quote!( #[ mutator( custom = true, hint = false ) ] ); + let meta = match input.meta + { + syn::Meta::List( ref meta_list ) => meta_list, + _ => panic!( "Expected a Meta::List" ), + }; + + let nested_meta_stream : &proc_macro2::TokenStream = &meta.tokens; + let attrs : StructAttributes = StructAttributes::from_attrs( std::iter::once( &input ) ).unwrap(); + println!( "{:?}", attrs ); + + let attr : AttributePropertyBoolean< AttributePropertyHintMarker > = AttributePropertyBoolean::default(); + assert_eq!( attr.internal(), false ); + let attr : AttributePropertyBoolean< AttributePropertyHintMarker > = true.into(); + assert_eq!( attr.internal(), true ); + let attr : AttributePropertyBoolean< AttributePropertyHintMarker > = false.into(); + assert_eq!( attr.internal(), false ); + + let input : syn::Attribute = syn::parse_quote!( #[ mutator( custom = true, hint = false ) ] ); + let meta = match input.meta + { + syn::Meta::List( ref meta_list ) => meta_list, + _ => panic!( "Expected a Meta::List" ), + }; + + let nested_meta_stream : &proc_macro2::TokenStream = &meta.tokens; + let parsed : StructAttributes = StructAttributes::from_attrs( std::iter::once( &input ) ).unwrap(); + assert_eq!( parsed.mutator.custom.internal(), true ); + assert_eq!( parsed.mutator.hint.internal(), false ); + +} diff --git a/module/core/macro_tools/tests/inc/attr_prop_test.rs b/module/core/macro_tools/tests/inc/attr_prop_test.rs index 8d2ff6c559..107e65d683 100644 --- a/module/core/macro_tools/tests/inc/attr_prop_test.rs +++ b/module/core/macro_tools/tests/inc/attr_prop_test.rs @@ -2,7 +2,7 @@ use super::*; use quote::ToTokens; #[ test ] -fn test_attribute_property_boolean() +fn attr_prop_test() { #[ derive( Debug, Default, Clone, Copy ) ] @@ -99,4 +99,5 @@ fn test_attribute_property_boolean() let parsed : MyAttributes = syn::parse2( nested_meta_stream ).unwrap(); assert_eq!( parsed.enabled.internal(), true ); assert_eq!( parsed.debug.internal(), false ); + } diff --git a/module/core/macro_tools/tests/inc/mod.rs b/module/core/macro_tools/tests/inc/mod.rs index 9ed0a80bee..09bce70fef 100644 --- a/module/core/macro_tools/tests/inc/mod.rs +++ b/module/core/macro_tools/tests/inc/mod.rs @@ -16,6 +16,7 @@ mod if_enabled mod attr_test; mod attr_prop_test; + mod attr_prop_example; mod basic_test; mod container_kind_test; mod derive_test; From fcd83794a1b603b86038afe558beb1dc501d1641 Mon Sep 17 00:00:00 2001 From: wandalen Date: Tue, 28 May 2024 00:35:49 +0300 Subject: [PATCH 03/59] derive_tools : utilizing attr props --- .../core/derive_tools_meta/src/derive/from.rs | 428 ++++++++++++++---- .../tests/inc/attr_prop_example.rs | 3 +- 2 files changed, 350 insertions(+), 81 deletions(-) diff --git a/module/core/derive_tools_meta/src/derive/from.rs b/module/core/derive_tools_meta/src/derive/from.rs index e3f330d149..dc31a91951 100644 --- a/module/core/derive_tools_meta/src/derive/from.rs +++ b/module/core/derive_tools_meta/src/derive/from.rs @@ -357,9 +357,28 @@ fn generate_unit /// Attributes of a field / variant /// +// xxx +use macro_tools:: +{ + attr, + syn_err, + return_syn_err, + qt, + Result, + AttributeComponent, + AttributePropertyComponent, + AttributePropertyBoolean, + AttributePropertyEnabled, +}; + +use former_types::{ ComponentAssign }; + +/// Represents the attributes of a struct. Aggregates all its attributes. +#[ derive( Debug, Default ) ] pub struct FieldAttributes { - pub from : Option< AttributeFrom >, + /// Attribute for customizing the mutation process. + pub from : AttributeFrom, } impl FieldAttributes @@ -367,12 +386,29 @@ impl FieldAttributes pub fn from_attrs< 'a >( attrs : impl Iterator< Item = &'a syn::Attribute > ) -> Result< Self > { - let mut from : Option< AttributeFrom > = None; + let mut result = Self::default(); + + let error = | attr : &syn::Attribute | -> syn::Error + { + let known_attributes = const_format::concatcp! + ( + "Known attirbutes are : ", + "debug", + ", ", AttributeFrom::KEYWORD, + ".", + ); + syn_err! + ( + attr, + "Expects an attribute of format '#[ attribute( key1 = val1, key2 = val2 ) ]'\n {known_attributes}\n But got: '{}'", + qt!{ #attr } + ) + }; for attr in attrs { - let key_ident = attr.path().get_ident() - .ok_or_else( || syn_err!( attr, "Expects an attribute of format #[ attribute( key1 = val1, key2 = val2 ) ], but got:\n {}", qt!{ #attr } ) )?; + + let key_ident = attr.path().get_ident().ok_or_else( || error( attr ) )?; let key_str = format!( "{}", key_ident ); if attr::is_standard( &key_str ) @@ -380,24 +416,15 @@ impl FieldAttributes continue; } - // qqq : qqq for Anton : xxx : refactor field_attrs::FieldAttributes::from_attrs to make it similar to this function match key_str.as_ref() { - AttributeFrom::KEYWORD => - { - from.replace( AttributeFrom::from_meta( attr )? ); - } - "debug" => - { - } - _ => - { - return Err( syn_err!( attr, "Known field attirbutes are : `from`, `debug`.\nUnknown structure attribute : {}", qt!{ #attr } ) ); - } + AttributeFrom::KEYWORD => result.assign( AttributeFrom::from_meta( attr )? ), + "debug" => {} + _ => return Err( error( attr ) ), } } - Ok( FieldAttributes { from } ) + Ok( result ) } } @@ -410,23 +437,57 @@ impl FieldAttributes /// `#[ from( off, hint : true ) ]` /// -#[ derive( Default ) ] +// #[ derive( Default ) ] +// pub struct AttributeFrom +// { +// /// Specifies whether we should generate From implementation for the field. +// /// Can be altered using `on` and `off` attributes +// pub enabled : Option< bool >, +// /// Specifies whether to provide a sketch of generated From or not. +// /// Defaults to `false`, which means no hint is provided unless explicitly requested. +// pub hint : bool, +// } +// +// impl AttributeFrom +// { +// +// const KEYWORD : &'static str = "from"; +// +// pub fn from_meta( attr : &syn::Attribute ) -> Result< Self > +// { +// match attr.meta +// { +// syn::Meta::List( ref meta_list ) => +// { +// return syn::parse2::< AttributeFrom >( meta_list.tokens.clone() ); +// }, +// syn::Meta::Path( ref _path ) => +// { +// return Ok( Default::default() ) +// }, +// _ => return_syn_err!( attr, "Expects an attribute of format #[ from( off ) ] +// .\nGot: {}", qt!{ #attr } ), +// } +// } +// +// } + +#[ derive( Debug, Default ) ] pub struct AttributeFrom { /// Specifies whether we should generate From implementation for the field. /// Can be altered using `on` and `off` attributes - pub enabled : Option< bool >, + pub enabled : AttributePropertyEnabled, /// Specifies whether to provide a sketch of generated From or not. /// Defaults to `false`, which means no hint is provided unless explicitly requested. - pub hint : bool, + pub hint : AttributePropertyHint, } -impl AttributeFrom +impl AttributeComponent for AttributeFrom { - const KEYWORD : &'static str = "from"; - pub fn from_meta( attr : &syn::Attribute ) -> Result< Self > + fn from_meta( attr : &syn::Attribute ) -> Result< Self > { match attr.meta { @@ -438,20 +499,70 @@ impl AttributeFrom { return Ok( Default::default() ) }, - _ => return_syn_err!( attr, "Expects an attribute of format #[ from( off ) ] -.\nGot: {}", qt!{ #attr } ), + _ => return_syn_err!( attr, "Expects an attribute of format `#[ from( on, hint = true ) ]`. \nGot: {}", qt!{ #attr } ), } } } +impl< IntoT > ComponentAssign< AttributeFrom, IntoT > for FieldAttributes +where + IntoT : Into< AttributeFrom >, +{ + #[ inline( always ) ] + fn assign( &mut self, component : IntoT ) + { + self.from = component.into(); + } +} + +impl< IntoT > ComponentAssign< AttributePropertyHint, IntoT > for AttributeFrom +where + IntoT : Into< AttributePropertyHint >, +{ + #[ inline( always ) ] + fn assign( &mut self, component : IntoT ) + { + self.hint = component.into(); + } +} + +impl< IntoT > ComponentAssign< AttributePropertyEnabled, IntoT > for AttributeFrom +where + IntoT : Into< AttributePropertyEnabled >, +{ + #[ inline( always ) ] + fn assign( &mut self, component : IntoT ) + { + self.custom = component.into(); + } +} + impl syn::parse::Parse for AttributeFrom { fn parse( input : syn::parse::ParseStream< '_ > ) -> syn::Result< Self > { - let mut off : bool = false; - let mut on : bool = false; - let mut hint = false; + let mut result = Self::default(); + + let error = | ident : &syn::Ident | -> syn::Error + { + let known = const_format::concatcp! + ( + "Known entries of attribute ", AttributeFrom::KEYWORD, " are : ", + AttributePropertyEnabled::KEYWORD, + ", ", AttributePropertyHint::KEYWORD, + ".", + ); + syn_err! + ( + ident, + r#"Expects an attribute of format '#[ from( custom = false, hint = false ) ]' + {known} + But got: '{}' +"#, + qt!{ #ident } + ) + }; while !input.is_empty() { @@ -459,69 +570,228 @@ impl syn::parse::Parse for AttributeFrom if lookahead.peek( syn::Ident ) { let ident : syn::Ident = input.parse()?; - // xxx : qqq for Anton : use match here and for all attributes -- done + + input.parse::< syn::Token![=] >()?; match ident.to_string().as_str() { - "off" => - { - input.parse::< syn::Token![ = ] >()?; - let value : syn::LitBool = input.parse()?; - off = value.value(); - }, - "on" => - { - input.parse::< syn::Token![ = ] >()?; - let value : syn::LitBool = input.parse()?; - on = value.value(); - } - "hint" => - { - input.parse::< syn::Token![ = ] >()?; - let value : syn::LitBool = input.parse()?; - hint = value.value; - } - _ => - { - return Err( syn::Error::new_spanned( &ident, format!( "Unexpected identifier '{}'. Expected 'on', 'off', or 'hint'. For example: `#[ from( off, hint : true ) ]`", ident ) ) ); - } + AttributePropertyEnabled::KEYWORD => result.assign( AttributePropertyEnabled::parse( input )? ), + AttributePropertyHint::KEYWORD => result.assign( AttributePropertyHint::parse( input )? ), + _ => return Err( error( &ident ) ), } } else { - return Err( syn::Error::new( input.span(), "Unexpected identifier '{}'. Expected 'on', 'off', or 'hint'. For example: `#[ from( off, hint : true ) ]`" ) ); + return Err( lookahead.error() ); } + // Optional comma handling + if input.peek( syn::Token![ , ] ) + { + input.parse::< syn::Token![ , ] >()?; + } } - // xxx : move on / off logic into a helper + Ok( result ) + } +} - let mut enabled : Option< bool > = None; +// == attribute properties - if on && off - { - // return Err( syn_err!( input, "`on` and `off` are mutually exclusive .\nIllegal attribute usage : {}", qt!{ #input } ) ) - return Err( syn::Error::new( input.span(), "`on` and `off` are mutually exclusive .\nIllegal attribute usage" ) ); - // xxx : test - } +/// Marker type for attribute property to specify whether to provide a sketch as a hint. +/// Defaults to `false`, which means no hint is provided unless explicitly requested. +#[ derive( Debug, Default, Clone, Copy ) ] +pub struct AttributePropertyHintMarker; - if !on && !off - { - enabled = None; - } - else if on - { - enabled = Some( true ) - } - else if off - { - enabled = Some( false ) - } +impl AttributePropertyComponent for AttributePropertyHintMarker +{ + const KEYWORD : &'static str = "hint"; +} - // Optional comma handling - if input.peek( syn::Token![ , ] ) - { - input.parse::< syn::Token![ , ] >()?; - } - Ok( Self { enabled, hint } ) - } +/// Specifies whether to provide a sketch as a hint. +/// Defaults to `false`, which means no hint is provided unless explicitly requested. +pub type AttributePropertyHint = AttributePropertyBoolean< AttributePropertyHintMarker >; + +// = + +/// Marker type for attribute property to indicates whether a custom code should be generated. +/// Defaults to `false`, meaning no custom code is generated unless explicitly requested. +#[ derive( Debug, Default, Clone, Copy ) ] +pub struct AttributePropertyEnabledMarker; + +impl AttributePropertyComponent for AttributePropertyEnabledMarker +{ + const KEYWORD : &'static str = "custom"; } + +/// Indicates whether a custom code should be generated. +/// Defaults to `false`, meaning no custom code is generated unless explicitly requested. +pub type AttributePropertyEnabled = AttributePropertyEnabled< AttributePropertyEnabledMarker >; + +// pub struct FieldAttributes +// { +// pub from : Option< AttributeFrom >, +// } +// +// impl FieldAttributes +// { +// +// pub fn from_attrs< 'a >( attrs : impl Iterator< Item = &'a syn::Attribute > ) -> Result< Self > +// { +// let mut from : Option< AttributeFrom > = None; +// +// for attr in attrs +// { +// let key_ident = attr.path().get_ident() +// .ok_or_else( || syn_err!( attr, "Expects an attribute of format #[ attribute( key1 = val1, key2 = val2 ) ], but got:\n {}", qt!{ #attr } ) )?; +// let key_str = format!( "{}", key_ident ); +// +// if attr::is_standard( &key_str ) +// { +// continue; +// } +// +// // qqq : qqq for Anton : xxx : refactor field_attrs::FieldAttributes::from_attrs to make it similar to this function +// match key_str.as_ref() +// { +// AttributeFrom::KEYWORD => +// { +// from.replace( AttributeFrom::from_meta( attr )? ); +// } +// "debug" => +// { +// } +// _ => +// { +// return Err( syn_err!( attr, "Known field attirbutes are : `from`, `debug`.\nUnknown structure attribute : {}", qt!{ #attr } ) ); +// } +// } +// } +// +// Ok( FieldAttributes { from } ) +// } +// +// } +// +// +// /// +// /// Attribute to hold parameters of forming for a specific field or variant. +// /// For example to avoid code From generation for it. +// /// +// /// `#[ from( off, hint : true ) ]` +// /// +// +// #[ derive( Default ) ] +// pub struct AttributeFrom +// { +// /// Specifies whether we should generate From implementation for the field. +// /// Can be altered using `on` and `off` attributes +// pub enabled : Option< bool >, +// /// Specifies whether to provide a sketch of generated From or not. +// /// Defaults to `false`, which means no hint is provided unless explicitly requested. +// pub hint : bool, +// } +// +// impl AttributeFrom +// { +// +// const KEYWORD : &'static str = "from"; +// +// pub fn from_meta( attr : &syn::Attribute ) -> Result< Self > +// { +// match attr.meta +// { +// syn::Meta::List( ref meta_list ) => +// { +// return syn::parse2::< AttributeFrom >( meta_list.tokens.clone() ); +// }, +// syn::Meta::Path( ref _path ) => +// { +// return Ok( Default::default() ) +// }, +// _ => return_syn_err!( attr, "Expects an attribute of format #[ from( off ) ] +// .\nGot: {}", qt!{ #attr } ), +// } +// } +// +// } +// +// impl syn::parse::Parse for AttributeFrom +// { +// fn parse( input : syn::parse::ParseStream< '_ > ) -> syn::Result< Self > +// { +// let mut off : bool = false; +// let mut on : bool = false; +// let mut hint = false; +// +// while !input.is_empty() +// { +// let lookahead = input.lookahead1(); +// if lookahead.peek( syn::Ident ) +// { +// let ident : syn::Ident = input.parse()?; +// // xxx : qqq for Anton : use match here and for all attributes -- done +// match ident.to_string().as_str() +// { +// "off" => +// { +// input.parse::< syn::Token![ = ] >()?; +// let value : syn::LitBool = input.parse()?; +// off = value.value(); +// }, +// "on" => +// { +// input.parse::< syn::Token![ = ] >()?; +// let value : syn::LitBool = input.parse()?; +// on = value.value(); +// } +// "hint" => +// { +// input.parse::< syn::Token![ = ] >()?; +// let value : syn::LitBool = input.parse()?; +// hint = value.value; +// } +// _ => +// { +// return Err( syn::Error::new_spanned( &ident, format!( "Unexpected identifier '{}'. Expected 'on', 'off', or 'hint'. For example: `#[ from( off, hint : true ) ]`", ident ) ) ); +// } +// } +// } +// else +// { +// return Err( syn::Error::new( input.span(), "Unexpected identifier '{}'. Expected 'on', 'off', or 'hint'. For example: `#[ from( off, hint : true ) ]`" ) ); +// } +// +// } +// +// // xxx : move on / off logic into a helper +// +// let mut enabled : Option< bool > = None; +// +// if on && off +// { +// // return Err( syn_err!( input, "`on` and `off` are mutually exclusive .\nIllegal attribute usage : {}", qt!{ #input } ) ) +// return Err( syn::Error::new( input.span(), "`on` and `off` are mutually exclusive .\nIllegal attribute usage" ) ); +// // xxx : test +// } +// +// if !on && !off +// { +// enabled = None; +// } +// else if on +// { +// enabled = Some( true ) +// } +// else if off +// { +// enabled = Some( false ) +// } +// +// // Optional comma handling +// if input.peek( syn::Token![ , ] ) +// { +// input.parse::< syn::Token![ , ] >()?; +// } +// Ok( Self { enabled, hint } ) +// } +// } diff --git a/module/core/macro_tools/tests/inc/attr_prop_example.rs b/module/core/macro_tools/tests/inc/attr_prop_example.rs index 85c260721f..16ba47b375 100644 --- a/module/core/macro_tools/tests/inc/attr_prop_example.rs +++ b/module/core/macro_tools/tests/inc/attr_prop_example.rs @@ -1,5 +1,4 @@ // use super::*; -// use quote::ToTokens; #[ test ] fn attr_props_draft() @@ -238,7 +237,7 @@ fn attr_props_draft() /// Defaults to `false`, meaning no custom code is generated unless explicitly requested. pub type AttributePropertyCustom = AttributePropertyBoolean< AttributePropertyCustomMarker >; - // == Test code + // == test code let input : syn::Attribute = syn::parse_quote!( #[ mutator( custom = true, hint = false ) ] ); let meta = match input.meta From 59ee6f634484236dc02ac989644044692da1aa61 Mon Sep 17 00:00:00 2001 From: wandalen Date: Tue, 28 May 2024 00:37:27 +0300 Subject: [PATCH 04/59] macro_tools : attr_props refactoring --- module/core/derive_tools_meta/src/derive/from.rs | 2 +- .../core/former_meta/src/derive_former/field_attrs.rs | 10 +++++----- .../core/former_meta/src/derive_former/struct_attrs.rs | 3 ++- module/core/macro_tools/src/attr_prop.rs | 4 ++-- module/core/macro_tools/tests/inc/attr_prop_example.rs | 2 +- module/core/macro_tools/tests/inc/attr_prop_test.rs | 2 +- 6 files changed, 12 insertions(+), 11 deletions(-) diff --git a/module/core/derive_tools_meta/src/derive/from.rs b/module/core/derive_tools_meta/src/derive/from.rs index dc31a91951..68d33865b1 100644 --- a/module/core/derive_tools_meta/src/derive/from.rs +++ b/module/core/derive_tools_meta/src/derive/from.rs @@ -571,7 +571,7 @@ impl syn::parse::Parse for AttributeFrom { let ident : syn::Ident = input.parse()?; - input.parse::< syn::Token![=] >()?; + input.parse::< syn::Token![ = ] >()?; match ident.to_string().as_str() { AttributePropertyEnabled::KEYWORD => result.assign( AttributePropertyEnabled::parse( input )? ), diff --git a/module/core/former_meta/src/derive_former/field_attrs.rs b/module/core/former_meta/src/derive_former/field_attrs.rs index a4f7a1357f..7c11683b99 100644 --- a/module/core/former_meta/src/derive_former/field_attrs.rs +++ b/module/core/former_meta/src/derive_former/field_attrs.rs @@ -203,7 +203,7 @@ impl syn::parse::Parse for AttributeConfig { let ident : syn::Ident = input.parse()?; - input.parse::< syn::Token![=] >()?; + input.parse::< syn::Token![ = ] >()?; match ident.to_string().as_str() { AttributePropertyDefault::KEYWORD => result.assign( AttributePropertyDefault::parse( input )? ), @@ -351,7 +351,7 @@ impl syn::parse::Parse for AttributeScalarSetter { let ident : syn::Ident = input.parse()?; - input.parse::< syn::Token![=] >()?; + input.parse::< syn::Token![ = ] >()?; match ident.to_string().as_str() { AttributePropertyName::KEYWORD => result.assign( AttributePropertyName::parse( input )? ), @@ -513,7 +513,7 @@ impl syn::parse::Parse for AttributeSubformScalarSetter { let ident : syn::Ident = input.parse()?; - input.parse::< syn::Token![=] >()?; + input.parse::< syn::Token![ = ] >()?; match ident.to_string().as_str() { AttributePropertyName::KEYWORD => result.assign( AttributePropertyName::parse( input )? ), @@ -744,7 +744,7 @@ impl syn::parse::Parse for AttributeSubformCollectionSetter { let ident : syn::Ident = input.parse()?; - input.parse::< syn::Token![=] >()?; + input.parse::< syn::Token![ = ] >()?; match ident.to_string().as_str() { AttributePropertyName::KEYWORD => result.assign( AttributePropertyName::parse( input )? ), @@ -914,7 +914,7 @@ impl syn::parse::Parse for AttributeSubformEntrySetter { let ident : syn::Ident = input.parse()?; - input.parse::< syn::Token![=] >()?; + input.parse::< syn::Token![ = ] >()?; match ident.to_string().as_str() { AttributePropertyName::KEYWORD => result.assign( AttributePropertyName::parse( input )? ), diff --git a/module/core/former_meta/src/derive_former/struct_attrs.rs b/module/core/former_meta/src/derive_former/struct_attrs.rs index a06bc9b275..345799772c 100644 --- a/module/core/former_meta/src/derive_former/struct_attrs.rs +++ b/module/core/former_meta/src/derive_former/struct_attrs.rs @@ -376,7 +376,8 @@ impl syn::parse::Parse for AttributeMutator { let ident : syn::Ident = input.parse()?; - input.parse::< syn::Token![=] >()?; + // xxx2 : move syn::Token![ = ] to attr prop + input.parse::< syn::Token![ = ] >()?; match ident.to_string().as_str() { AttributePropertyCustom::KEYWORD => result.assign( AttributePropertyCustom::parse( input )? ), diff --git a/module/core/macro_tools/src/attr_prop.rs b/module/core/macro_tools/src/attr_prop.rs index 711afe225c..075cde029b 100644 --- a/module/core/macro_tools/src/attr_prop.rs +++ b/module/core/macro_tools/src/attr_prop.rs @@ -47,7 +47,7 @@ //! if lookahead.peek( syn::Ident ) //! { //! let ident : syn::Ident = input.parse()?; -//! input.parse::< syn::Token![=] >()?; +//! input.parse::< syn::Token![ = ] >()?; //! match ident.to_string().as_str() //! { //! DebugMarker::KEYWORD => debug = input.parse()?, @@ -152,7 +152,7 @@ pub( crate ) mod private /// if lookahead.peek( syn::Ident ) /// { /// let ident : syn::Ident = input.parse()?; - /// input.parse::< syn::Token![=] >()?; + /// input.parse::< syn::Token![ = ] >()?; /// match ident.to_string().as_str() /// { /// DebugMarker::KEYWORD => debug = input.parse()?, diff --git a/module/core/macro_tools/tests/inc/attr_prop_example.rs b/module/core/macro_tools/tests/inc/attr_prop_example.rs index 16ba47b375..d86b07e2cb 100644 --- a/module/core/macro_tools/tests/inc/attr_prop_example.rs +++ b/module/core/macro_tools/tests/inc/attr_prop_example.rs @@ -181,7 +181,7 @@ fn attr_props_draft() { let ident : syn::Ident = input.parse()?; - input.parse::< syn::Token![=] >()?; + input.parse::< syn::Token![ = ] >()?; match ident.to_string().as_str() { AttributePropertyCustom::KEYWORD => result.assign( AttributePropertyCustom::parse( input )? ), diff --git a/module/core/macro_tools/tests/inc/attr_prop_test.rs b/module/core/macro_tools/tests/inc/attr_prop_test.rs index 107e65d683..6779119be7 100644 --- a/module/core/macro_tools/tests/inc/attr_prop_test.rs +++ b/module/core/macro_tools/tests/inc/attr_prop_test.rs @@ -46,7 +46,7 @@ fn attr_prop_test() if lookahead.peek( syn::Ident ) { let ident : syn::Ident = input.parse()?; - input.parse::< syn::Token![=] >()?; + input.parse::< syn::Token![ = ] >()?; match ident.to_string().as_str() { DebugMarker::KEYWORD => debug = input.parse()?, From e465730219a3099f659df16b5d5de1c86bad6770 Mon Sep 17 00:00:00 2001 From: wandalen Date: Tue, 28 May 2024 09:48:07 +0300 Subject: [PATCH 05/59] macro_tools : attr_props refactoring and examples --- .../core/derive_tools_meta/src/derive/from.rs | 2 - .../src/derive_former/field_attrs.rs | 8 - .../src/derive_former/struct_attrs.rs | 3 - module/core/macro_tools/Readme.md | 325 +++++++++++++++++- .../macro_tools_attr_prop.rs} | 147 ++++---- .../examples/macro_tools_trivial.rs | 34 +- module/core/macro_tools/src/attr_prop.rs | 6 +- .../macro_tools/tests/inc/attr_prop_test.rs | 1 - 8 files changed, 427 insertions(+), 99 deletions(-) rename module/core/macro_tools/{tests/inc/attr_prop_example.rs => examples/macro_tools_attr_prop.rs} (58%) diff --git a/module/core/derive_tools_meta/src/derive/from.rs b/module/core/derive_tools_meta/src/derive/from.rs index 68d33865b1..2594f779d4 100644 --- a/module/core/derive_tools_meta/src/derive/from.rs +++ b/module/core/derive_tools_meta/src/derive/from.rs @@ -429,7 +429,6 @@ impl FieldAttributes } - /// /// Attribute to hold parameters of forming for a specific field or variant. /// For example to avoid code From generation for it. @@ -571,7 +570,6 @@ impl syn::parse::Parse for AttributeFrom { let ident : syn::Ident = input.parse()?; - input.parse::< syn::Token![ = ] >()?; match ident.to_string().as_str() { AttributePropertyEnabled::KEYWORD => result.assign( AttributePropertyEnabled::parse( input )? ), diff --git a/module/core/former_meta/src/derive_former/field_attrs.rs b/module/core/former_meta/src/derive_former/field_attrs.rs index 7c11683b99..d9f46b6ac9 100644 --- a/module/core/former_meta/src/derive_former/field_attrs.rs +++ b/module/core/former_meta/src/derive_former/field_attrs.rs @@ -202,8 +202,6 @@ impl syn::parse::Parse for AttributeConfig if lookahead.peek( syn::Ident ) { let ident : syn::Ident = input.parse()?; - - input.parse::< syn::Token![ = ] >()?; match ident.to_string().as_str() { AttributePropertyDefault::KEYWORD => result.assign( AttributePropertyDefault::parse( input )? ), @@ -350,8 +348,6 @@ impl syn::parse::Parse for AttributeScalarSetter if lookahead.peek( syn::Ident ) { let ident : syn::Ident = input.parse()?; - - input.parse::< syn::Token![ = ] >()?; match ident.to_string().as_str() { AttributePropertyName::KEYWORD => result.assign( AttributePropertyName::parse( input )? ), @@ -743,8 +739,6 @@ impl syn::parse::Parse for AttributeSubformCollectionSetter if lookahead.peek( syn::Ident ) { let ident : syn::Ident = input.parse()?; - - input.parse::< syn::Token![ = ] >()?; match ident.to_string().as_str() { AttributePropertyName::KEYWORD => result.assign( AttributePropertyName::parse( input )? ), @@ -913,8 +907,6 @@ impl syn::parse::Parse for AttributeSubformEntrySetter if lookahead.peek( syn::Ident ) { let ident : syn::Ident = input.parse()?; - - input.parse::< syn::Token![ = ] >()?; match ident.to_string().as_str() { AttributePropertyName::KEYWORD => result.assign( AttributePropertyName::parse( input )? ), diff --git a/module/core/former_meta/src/derive_former/struct_attrs.rs b/module/core/former_meta/src/derive_former/struct_attrs.rs index 345799772c..74ec9f39c7 100644 --- a/module/core/former_meta/src/derive_former/struct_attrs.rs +++ b/module/core/former_meta/src/derive_former/struct_attrs.rs @@ -375,9 +375,6 @@ impl syn::parse::Parse for AttributeMutator if lookahead.peek( syn::Ident ) { let ident : syn::Ident = input.parse()?; - - // xxx2 : move syn::Token![ = ] to attr prop - input.parse::< syn::Token![ = ] >()?; match ident.to_string().as_str() { AttributePropertyCustom::KEYWORD => result.assign( AttributePropertyCustom::parse( input )? ), diff --git a/module/core/macro_tools/Readme.md b/module/core/macro_tools/Readme.md index cf396b008f..1add7411f8 100644 --- a/module/core/macro_tools/Readme.md +++ b/module/core/macro_tools/Readme.md @@ -7,27 +7,339 @@ Tools for writing procedural macros. -### Basic use-case +### Example: Trivial One +The purpose of `typ::type_parameters` is to extract type parameters from a given Rust type. +In this example, we generate a type `core::option::Option` and extract its type parameters. + ```rust +#[ cfg( not( feature = "enabled" ) ) ] +fn main(){} #[ cfg( feature = "enabled" ) ] +fn main() { - use macro_tools::exposed::*; + // Import necessary macros and modules from the `macro_tools` crate. + use macro_tools::{ typ, qt }; + // Generate a token stream representing the type `core::option::Option`. let code = qt!( core::option::Option< i8, i16, i32, i64 > ); + + // Parse the generated token stream into a `syn::Type` object. + // `syn::Type` is a syntax tree node representing a Rust type. let tree_type = syn::parse2::< syn::Type >( code ).unwrap(); + + // Extract type parameters from the parsed type. + // `typ::type_parameters` takes a reference to a `syn::Type` and a range. + // It returns a vector of type parameters within the specified range. + // Here, `0..=2` specifies that we are interested in the first three type parameters. let got = typ::type_parameters( &tree_type, 0..=2 ); + + // Iterate over the extracted type parameters and print each one. + // The `qt!` macro is used to convert the type parameter back to a token stream for printing. got.iter().for_each( | e | println!( "{}", qt!( #e ) ) ); - /* print : - i8 - i16 - i32 + + /* Expected output: + i8 + i16 + i32 */ } ``` +Try out `cargo run --example macro_tools_trivial`. +
+[See code](./examples/macro_tools_trivial.rs). + +### Example: Attribute Properties + +This example demonstrates an approach to parsing attributes and their properties. +The attributes are collected into a struct that aggregates them, and attribute properties +are parsed using reusable components from a library. The example shows how to use +`AttributePropertyBoolean` for parsing boolean properties and the roles of the traits +`AttributePropertyComponent` and `AttributeComponent`. The `ComponentAssign` trait is +also used to simplify the logic of assigning fields. + +Attributes are collected into a `StructAttributes` struct, and attribute properties are parsed +using reusable components like `AttributePropertyBoolean`. + +- `AttributeComponent`: A trait that defines how an attribute should be parsed from a `syn::Attribute`. +- `AttributePropertyComponent`: A trait that defines a marker for attribute properties. +- `ComponentAssign`: A trait that simplifies the logic of assigning fields to a struct. Using a +component-based approach requires each field to have a unique type, which aligns with the +strengths of strongly-typed languages. This method ensures that the logic of +assigning values to fields is encapsulated within the fields themselves, promoting modularity +and reusability. + +The reusable property components from the library come with parameters that distinguish +different properties of the same type. This is useful when an attribute has multiple boolean +properties, for instance. Such an approach helps to avoid limitations where it is +always possible to define traits for custom types, while it may not be possible for types +defined in other crates. + +```rust + +#[ cfg( not( all( feature = "enabled", debug_assertions ) ) ) ] +fn main(){} +#[ cfg( all( feature = "enabled", debug_assertions ) ) ] +fn main() +{ + + use macro_tools:: + { + attr, syn_err, return_syn_err, qt, Result, AttributeComponent, + AttributePropertyComponent, AttributePropertyBoolean, + }; + use former_types::ComponentAssign; + + /// Represents the attributes of a struct. Aggregates all its attributes. + #[ derive( Debug, Default ) ] + pub struct StructAttributes + { + /// Attribute for customizing the mutation process. + pub mutator : AttributeMutator, + } + + impl StructAttributes + { + /// Constructs a `StructAttributes` instance from an iterator of attributes. + /// + /// This function parses the provided attributes and assigns them to the + /// appropriate fields in the `StructAttributes` struct. + pub fn from_attrs< 'a >( attrs : impl Iterator< Item = & 'a syn::Attribute > ) -> Result< Self > + { + let mut result = Self::default(); + + // Closure to generate an error message for unknown attributes. + let error = | attr : & syn::Attribute | -> syn::Error + { + let known_attributes = const_format::concatcp! + ( + "Known attributes are: ", + "debug", + ", ", AttributeMutator::KEYWORD, + "." + ); + syn_err! + ( + attr, + "Expects an attribute of format '#[ attribute( key1 = val1, key2 = val2 ) ]'\n {known_attributes}\n But got: '{}'", + qt! { #attr } + ) + }; + + for attr in attrs + { + let key_ident = attr.path().get_ident().ok_or_else( || error( attr ) )?; + let key_str = format!( "{}", key_ident ); + if attr::is_standard( & key_str ) + { + continue; + } + match key_str.as_ref() + { + AttributeMutator::KEYWORD => result.assign( AttributeMutator::from_meta( attr )? ), + "debug" => {}, + _ => return Err( error( attr ) ), + } + } + + Ok( result ) + } + } + + /// Represents attributes for customizing the mutation process in a forming operation. + /// + /// ## Example of code + /// + /// ```ignore + /// #[ mutator( custom = true, hint = true ) ] + /// ``` + #[ derive( Debug, Default ) ] + pub struct AttributeMutator + { + /// Indicates whether a custom mutator should be generated. + /// Defaults to `false`, meaning no custom mutator is generated unless explicitly requested. + pub custom : AttributePropertyCustom, + /// Specifies whether to provide a sketch of the mutator as a hint. + /// Defaults to `false`, which means no hint is provided unless explicitly requested. + pub hint : AttributePropertyHint, + } + + impl AttributeComponent for AttributeMutator + { + const KEYWORD : & 'static str = "mutator"; + + /// Parses a `syn::Attribute` into an `AttributeMutator`. + fn from_meta( attr : & syn::Attribute ) -> Result< Self > + { + match attr.meta + { + syn::Meta::List( ref meta_list ) => + { + return syn::parse2::< AttributeMutator >( meta_list.tokens.clone() ); + }, + syn::Meta::Path( ref _path ) => + { + return Ok( Default::default() ) + }, + _ => return_syn_err! + ( + attr, + "Expects an attribute of format `#[ mutator( custom = true, hint = true ) ]`. \nGot: {}", + qt! { #attr } + ), + } + } + } + + // Implement `ComponentAssign` trait to allow assigning `AttributeMutator` to `StructAttributes`. + impl< IntoT > ComponentAssign< AttributeMutator, IntoT > for StructAttributes + where + IntoT : Into< AttributeMutator >, + { + #[ inline( always ) ] + fn assign( & mut self, component : IntoT ) + { + self.mutator = component.into(); + } + } + + // Implement `ComponentAssign` trait to allow assigning `AttributePropertyHint` to `AttributeMutator`. + impl< IntoT > ComponentAssign< AttributePropertyHint, IntoT > for AttributeMutator + where + IntoT : Into< AttributePropertyHint >, + { + #[ inline( always ) ] + fn assign( & mut self, component : IntoT ) + { + self.hint = component.into(); + } + } + + // Implement `ComponentAssign` trait to allow assigning `AttributePropertyCustom` to `AttributeMutator`. + impl< IntoT > ComponentAssign< AttributePropertyCustom, IntoT > for AttributeMutator + where + IntoT : Into< AttributePropertyCustom >, + { + #[ inline( always ) ] + fn assign( & mut self, component : IntoT ) + { + self.custom = component.into(); + } + } + + impl syn::parse::Parse for AttributeMutator + { + fn parse( input : syn::parse::ParseStream< '_ > ) -> syn::Result< Self > + { + let mut result = Self::default(); + + let error = | ident : & syn::Ident | -> syn::Error + { + let known = const_format::concatcp! + ( + "Known entries of attribute ", AttributeMutator::KEYWORD, " are: ", + AttributePropertyCustom::KEYWORD, + ", ", AttributePropertyHint::KEYWORD, + "." + ); + syn_err! + ( + ident, + r#"Expects an attribute of format '#[ mutator( custom = false, hint = false ) ]' + {known} + But got: '{}' + "#, + qt! { #ident } + ) + }; + + while !input.is_empty() + { + let lookahead = input.lookahead1(); + if lookahead.peek( syn::Ident ) + { + let ident : syn::Ident = input.parse()?; + + match ident.to_string().as_str() + { + AttributePropertyCustom::KEYWORD => result.assign( AttributePropertyCustom::parse( input )? ), + AttributePropertyHint::KEYWORD => result.assign( AttributePropertyHint::parse( input )? ), + _ => return Err( error( & ident ) ), + } + } + else + { + return Err( lookahead.error() ); + } + + // Optional comma handling + if input.peek( syn::Token![,] ) + { + input.parse::< syn::Token![,] >()?; + } + } + + Ok( result ) + } + } + + // == Attribute properties + + /// Marker type for attribute property to specify whether to provide a sketch as a hint. + /// Defaults to `false`, which means no hint is provided unless explicitly requested. + #[ derive( Debug, Default, Clone, Copy ) ] + pub struct AttributePropertyHintMarker; + + impl AttributePropertyComponent for AttributePropertyHintMarker + { + const KEYWORD : & 'static str = "hint"; + } + + /// Specifies whether to provide a sketch as a hint. + /// Defaults to `false`, which means no hint is provided unless explicitly requested. + pub type AttributePropertyHint = AttributePropertyBoolean< AttributePropertyHintMarker >; + + // == + + /// Marker type for attribute property to indicate whether a custom code should be generated. + /// Defaults to `false`, meaning no custom code is generated unless explicitly requested. + #[ derive( Debug, Default, Clone, Copy ) ] + pub struct AttributePropertyCustomMarker; + + impl AttributePropertyComponent for AttributePropertyCustomMarker + { + const KEYWORD : & 'static str = "custom"; + } + + /// Indicates whether a custom code should be generated. + /// Defaults to `false`, meaning no custom code is generated unless explicitly requested. + pub type AttributePropertyCustom = AttributePropertyBoolean< AttributePropertyCustomMarker >; + + // == Test code + + // Parse an attribute and construct a `StructAttributes` instance. + let input : syn::Attribute = syn::parse_quote!( #[ mutator( custom = true, hint = false ) ] ); + let attrs : StructAttributes = StructAttributes::from_attrs( std::iter::once( & input ) ).unwrap(); + println!( "{:?}", attrs ); + + // Test `AttributePropertyBoolean` functionality. + let attr : AttributePropertyBoolean< AttributePropertyHintMarker > = AttributePropertyBoolean::default(); + assert_eq!( attr.internal(), false ); + let attr : AttributePropertyBoolean< AttributePropertyHintMarker > = true.into(); + assert_eq!( attr.internal(), true ); + let attr : AttributePropertyBoolean< AttributePropertyHintMarker > = false.into(); + assert_eq!( attr.internal(), false ); + +} +``` + +Try out `cargo run --example macro_tools_attr_prop`. +
+[See code](./examples/macro_tools_attr_prop.rs). + ### To add to your project ```sh @@ -42,4 +354,3 @@ cd wTools cd examples/macro_tools_trivial cargo run ``` - diff --git a/module/core/macro_tools/tests/inc/attr_prop_example.rs b/module/core/macro_tools/examples/macro_tools_attr_prop.rs similarity index 58% rename from module/core/macro_tools/tests/inc/attr_prop_example.rs rename to module/core/macro_tools/examples/macro_tools_attr_prop.rs index d86b07e2cb..1ae5caa3eb 100644 --- a/module/core/macro_tools/tests/inc/attr_prop_example.rs +++ b/module/core/macro_tools/examples/macro_tools_attr_prop.rs @@ -1,22 +1,43 @@ -// use super::*; - -#[ test ] -fn attr_props_draft() +//! +//! ### Example: Attribute Properties +//! +//! This example demonstrates an approach to parsing attributes and their properties. +//! The attributes are collected into a struct that aggregates them, and attribute properties +//! are parsed using reusable components from a library. The example shows how to use +//! `AttributePropertyBoolean` for parsing boolean properties and the roles of the traits +//! `AttributePropertyComponent` and `AttributeComponent`. The `ComponentAssign` trait is +//! also used to simplify the logic of assigning fields. +//! +//! Attributes are collected into a `StructAttributes` struct, and attribute properties are parsed +//! using reusable components like `AttributePropertyBoolean`. +//! +//! - `AttributeComponent`: A trait that defines how an attribute should be parsed from a `syn::Attribute`. +//! - `AttributePropertyComponent`: A trait that defines a marker for attribute properties. +//! - `ComponentAssign`: A trait that simplifies the logic of assigning fields to a struct. Using a +//! component-based approach requires each field to have a unique type, which aligns with the +//! strengths of strongly-typed languages. This method ensures that the logic of +//! assigning values to fields is encapsulated within the fields themselves, promoting modularity +//! and reusability. +//! +//! The reusable property components from the library come with parameters that distinguish +//! different properties of the same type. This is useful when an attribute has multiple boolean +//! properties, for instance. Such an approach helps to avoid limitations where it is +//! always possible to define traits for custom types, while it may not be possible for types +//! defined in other crates. +//! + +#[ cfg( not( all( feature = "enabled", debug_assertions ) ) ) ] +fn main(){} +#[ cfg( all( feature = "enabled", debug_assertions ) ) ] +fn main() { use macro_tools:: { - attr, - syn_err, - return_syn_err, - qt, - Result, - AttributeComponent, - AttributePropertyComponent, - AttributePropertyBoolean, + attr, syn_err, return_syn_err, qt, Result, AttributeComponent, + AttributePropertyComponent, AttributePropertyBoolean, }; - - use former_types::{ ComponentAssign }; + use former_types::ComponentAssign; /// Represents the attributes of a struct. Aggregates all its attributes. #[ derive( Debug, Default ) ] @@ -28,50 +49,50 @@ fn attr_props_draft() impl StructAttributes { - - pub fn from_attrs< 'a >( attrs : impl Iterator< Item = &'a syn::Attribute > ) -> Result< Self > + /// Constructs a `StructAttributes` instance from an iterator of attributes. + /// + /// This function parses the provided attributes and assigns them to the + /// appropriate fields in the `StructAttributes` struct. + pub fn from_attrs< 'a >( attrs : impl Iterator< Item = & 'a syn::Attribute > ) -> Result< Self > { let mut result = Self::default(); - let error = | attr : &syn::Attribute | -> syn::Error + // Closure to generate an error message for unknown attributes. + let error = | attr : & syn::Attribute | -> syn::Error { let known_attributes = const_format::concatcp! ( - "Known attirbutes are : ", + "Known attributes are: ", "debug", ", ", AttributeMutator::KEYWORD, - ".", + "." ); syn_err! ( attr, "Expects an attribute of format '#[ attribute( key1 = val1, key2 = val2 ) ]'\n {known_attributes}\n But got: '{}'", - qt!{ #attr } + qt! { #attr } ) }; for attr in attrs { - let key_ident = attr.path().get_ident().ok_or_else( || error( attr ) )?; let key_str = format!( "{}", key_ident ); - - if attr::is_standard( &key_str ) + if attr::is_standard( & key_str ) { continue; } - match key_str.as_ref() { AttributeMutator::KEYWORD => result.assign( AttributeMutator::from_meta( attr )? ), - "debug" => {} + "debug" => {}, _ => return Err( error( attr ) ), } } Ok( result ) } - } /// Represents attributes for customizing the mutation process in a forming operation. @@ -81,7 +102,6 @@ fn attr_props_draft() /// ```ignore /// #[ mutator( custom = true, hint = true ) ] /// ``` - #[ derive( Debug, Default ) ] pub struct AttributeMutator { @@ -95,9 +115,10 @@ fn attr_props_draft() impl AttributeComponent for AttributeMutator { - const KEYWORD : &'static str = "mutator"; + const KEYWORD : & 'static str = "mutator"; - fn from_meta( attr : &syn::Attribute ) -> Result< Self > + /// Parses a `syn::Attribute` into an `AttributeMutator`. + fn from_meta( attr : & syn::Attribute ) -> Result< Self > { match attr.meta { @@ -109,40 +130,47 @@ fn attr_props_draft() { return Ok( Default::default() ) }, - _ => return_syn_err!( attr, "Expects an attribute of format `#[ mutator( custom = true, hint = true ) ]`. \nGot: {}", qt!{ #attr } ), + _ => return_syn_err! + ( + attr, + "Expects an attribute of format `#[ mutator( custom = true, hint = true ) ]`. \nGot: {}", + qt! { #attr } + ), } } - } + // Implement `ComponentAssign` trait to allow assigning `AttributeMutator` to `StructAttributes`. impl< IntoT > ComponentAssign< AttributeMutator, IntoT > for StructAttributes where IntoT : Into< AttributeMutator >, { #[ inline( always ) ] - fn assign( &mut self, component : IntoT ) + fn assign( & mut self, component : IntoT ) { self.mutator = component.into(); } } + // Implement `ComponentAssign` trait to allow assigning `AttributePropertyHint` to `AttributeMutator`. impl< IntoT > ComponentAssign< AttributePropertyHint, IntoT > for AttributeMutator where IntoT : Into< AttributePropertyHint >, { #[ inline( always ) ] - fn assign( &mut self, component : IntoT ) + fn assign( & mut self, component : IntoT ) { self.hint = component.into(); } } + // Implement `ComponentAssign` trait to allow assigning `AttributePropertyCustom` to `AttributeMutator`. impl< IntoT > ComponentAssign< AttributePropertyCustom, IntoT > for AttributeMutator where IntoT : Into< AttributePropertyCustom >, { #[ inline( always ) ] - fn assign( &mut self, component : IntoT ) + fn assign( & mut self, component : IntoT ) { self.custom = component.into(); } @@ -154,14 +182,14 @@ fn attr_props_draft() { let mut result = Self::default(); - let error = | ident : &syn::Ident | -> syn::Error + let error = | ident : & syn::Ident | -> syn::Error { let known = const_format::concatcp! ( - "Known entries of attribute ", AttributeMutator::KEYWORD, " are : ", + "Known entries of attribute ", AttributeMutator::KEYWORD, " are: ", AttributePropertyCustom::KEYWORD, ", ", AttributePropertyHint::KEYWORD, - ".", + "." ); syn_err! ( @@ -170,7 +198,7 @@ fn attr_props_draft() {known} But got: '{}' "#, - qt!{ #ident } + qt! { #ident } ) }; @@ -181,12 +209,11 @@ fn attr_props_draft() { let ident : syn::Ident = input.parse()?; - input.parse::< syn::Token![ = ] >()?; match ident.to_string().as_str() { AttributePropertyCustom::KEYWORD => result.assign( AttributePropertyCustom::parse( input )? ), AttributePropertyHint::KEYWORD => result.assign( AttributePropertyHint::parse( input )? ), - _ => return Err( error( &ident ) ), + _ => return Err( error( & ident ) ), } } else @@ -195,9 +222,9 @@ fn attr_props_draft() } // Optional comma handling - if input.peek( syn::Token![ , ] ) + if input.peek( syn::Token![,] ) { - input.parse::< syn::Token![ , ] >()?; + input.parse::< syn::Token![,] >()?; } } @@ -205,7 +232,7 @@ fn attr_props_draft() } } - // == attribute properties + // == Attribute properties /// Marker type for attribute property to specify whether to provide a sketch as a hint. /// Defaults to `false`, which means no hint is provided unless explicitly requested. @@ -214,59 +241,41 @@ fn attr_props_draft() impl AttributePropertyComponent for AttributePropertyHintMarker { - const KEYWORD : &'static str = "hint"; + const KEYWORD : & 'static str = "hint"; } /// Specifies whether to provide a sketch as a hint. /// Defaults to `false`, which means no hint is provided unless explicitly requested. pub type AttributePropertyHint = AttributePropertyBoolean< AttributePropertyHintMarker >; - // = + // == - /// Marker type for attribute property to indicates whether a custom code should be generated. + /// Marker type for attribute property to indicate whether a custom code should be generated. /// Defaults to `false`, meaning no custom code is generated unless explicitly requested. #[ derive( Debug, Default, Clone, Copy ) ] pub struct AttributePropertyCustomMarker; impl AttributePropertyComponent for AttributePropertyCustomMarker { - const KEYWORD : &'static str = "custom"; + const KEYWORD : & 'static str = "custom"; } /// Indicates whether a custom code should be generated. /// Defaults to `false`, meaning no custom code is generated unless explicitly requested. pub type AttributePropertyCustom = AttributePropertyBoolean< AttributePropertyCustomMarker >; - // == test code + // == Test code + // Parse an attribute and construct a `StructAttributes` instance. let input : syn::Attribute = syn::parse_quote!( #[ mutator( custom = true, hint = false ) ] ); - let meta = match input.meta - { - syn::Meta::List( ref meta_list ) => meta_list, - _ => panic!( "Expected a Meta::List" ), - }; - - let nested_meta_stream : &proc_macro2::TokenStream = &meta.tokens; - let attrs : StructAttributes = StructAttributes::from_attrs( std::iter::once( &input ) ).unwrap(); + let attrs : StructAttributes = StructAttributes::from_attrs( std::iter::once( & input ) ).unwrap(); println!( "{:?}", attrs ); + // Test `AttributePropertyBoolean` functionality. let attr : AttributePropertyBoolean< AttributePropertyHintMarker > = AttributePropertyBoolean::default(); assert_eq!( attr.internal(), false ); let attr : AttributePropertyBoolean< AttributePropertyHintMarker > = true.into(); assert_eq!( attr.internal(), true ); let attr : AttributePropertyBoolean< AttributePropertyHintMarker > = false.into(); assert_eq!( attr.internal(), false ); - - let input : syn::Attribute = syn::parse_quote!( #[ mutator( custom = true, hint = false ) ] ); - let meta = match input.meta - { - syn::Meta::List( ref meta_list ) => meta_list, - _ => panic!( "Expected a Meta::List" ), - }; - - let nested_meta_stream : &proc_macro2::TokenStream = &meta.tokens; - let parsed : StructAttributes = StructAttributes::from_attrs( std::iter::once( &input ) ).unwrap(); - assert_eq!( parsed.mutator.custom.internal(), true ); - assert_eq!( parsed.mutator.hint.internal(), false ); - } diff --git a/module/core/macro_tools/examples/macro_tools_trivial.rs b/module/core/macro_tools/examples/macro_tools_trivial.rs index 73cd1af6c8..e92559b193 100644 --- a/module/core/macro_tools/examples/macro_tools_trivial.rs +++ b/module/core/macro_tools/examples/macro_tools_trivial.rs @@ -1,19 +1,39 @@ -//! qqq : write proper description +//! This example demonstrates the use of `typ::type_parameters` from the `macro_tools` crate. +//! +//! ### Example: Trivial One +//! +//! The purpose of `typ::type_parameters` is to extract type parameters from a given Rust type. +//! In this example, we generate a type `core::option::Option` and extract its type parameters. +//! + #[ cfg( not( feature = "enabled" ) ) ] fn main(){} - #[ cfg( feature = "enabled" ) ] fn main() { + // Import necessary macros and modules from the `macro_tools` crate. use macro_tools::{ typ, qt }; + // Generate a token stream representing the type `core::option::Option`. let code = qt!( core::option::Option< i8, i16, i32, i64 > ); + + // Parse the generated token stream into a `syn::Type` object. + // `syn::Type` is a syntax tree node representing a Rust type. let tree_type = syn::parse2::< syn::Type >( code ).unwrap(); + + // Extract type parameters from the parsed type. + // `typ::type_parameters` takes a reference to a `syn::Type` and a range. + // It returns a vector of type parameters within the specified range. + // Here, `0..=2` specifies that we are interested in the first three type parameters. let got = typ::type_parameters( &tree_type, 0..=2 ); + + // Iterate over the extracted type parameters and print each one. + // The `qt!` macro is used to convert the type parameter back to a token stream for printing. got.iter().for_each( | e | println!( "{}", qt!( #e ) ) ); - /* print : - i8 - i16 - i32 + + /* Expected output: + i8 + i16 + i32 */ -} \ No newline at end of file +} diff --git a/module/core/macro_tools/src/attr_prop.rs b/module/core/macro_tools/src/attr_prop.rs index 075cde029b..f75491dae1 100644 --- a/module/core/macro_tools/src/attr_prop.rs +++ b/module/core/macro_tools/src/attr_prop.rs @@ -47,7 +47,6 @@ //! if lookahead.peek( syn::Ident ) //! { //! let ident : syn::Ident = input.parse()?; -//! input.parse::< syn::Token![ = ] >()?; //! match ident.to_string().as_str() //! { //! DebugMarker::KEYWORD => debug = input.parse()?, @@ -152,7 +151,6 @@ pub( crate ) mod private /// if lookahead.peek( syn::Ident ) /// { /// let ident : syn::Ident = input.parse()?; - /// input.parse::< syn::Token![ = ] >()?; /// match ident.to_string().as_str() /// { /// DebugMarker::KEYWORD => debug = input.parse()?, @@ -230,6 +228,7 @@ pub( crate ) mod private { fn parse( input : syn::parse::ParseStream< '_ > ) -> syn::Result< Self > { + input.parse::< syn::Token![ = ] >()?; let value : syn::LitBool = input.parse()?; Ok( value.value.into() ) } @@ -306,6 +305,7 @@ pub( crate ) mod private { fn parse( input : syn::parse::ParseStream< '_ > ) -> syn::Result< Self > { + input.parse::< syn::Token![ = ] >()?; let value : syn::LitBool = input.parse()?; Ok( value.value.into() ) } @@ -400,6 +400,7 @@ pub( crate ) mod private { fn parse( input : syn::parse::ParseStream< '_ > ) -> syn::Result< Self > { + input.parse::< syn::Token![ = ] >()?; let value : T = input.parse()?; Ok( value.into() ) } @@ -497,6 +498,7 @@ pub( crate ) mod private { fn parse( input : syn::parse::ParseStream< '_ > ) -> syn::Result< Self > { + input.parse::< syn::Token![ = ] >()?; let value : T = input.parse()?; Ok( value.into() ) } diff --git a/module/core/macro_tools/tests/inc/attr_prop_test.rs b/module/core/macro_tools/tests/inc/attr_prop_test.rs index 6779119be7..6274513ad2 100644 --- a/module/core/macro_tools/tests/inc/attr_prop_test.rs +++ b/module/core/macro_tools/tests/inc/attr_prop_test.rs @@ -46,7 +46,6 @@ fn attr_prop_test() if lookahead.peek( syn::Ident ) { let ident : syn::Ident = input.parse()?; - input.parse::< syn::Token![ = ] >()?; match ident.to_string().as_str() { DebugMarker::KEYWORD => debug = input.parse()?, From d40ba40c2c7dbe73e23f96a79078e4e02579c3eb Mon Sep 17 00:00:00 2001 From: wandalen Date: Tue, 28 May 2024 09:48:35 +0300 Subject: [PATCH 06/59] macro_tools : attr_props refactoring and examples --- module/core/macro_tools/tests/inc/mod.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/module/core/macro_tools/tests/inc/mod.rs b/module/core/macro_tools/tests/inc/mod.rs index 09bce70fef..9ed0a80bee 100644 --- a/module/core/macro_tools/tests/inc/mod.rs +++ b/module/core/macro_tools/tests/inc/mod.rs @@ -16,7 +16,6 @@ mod if_enabled mod attr_test; mod attr_prop_test; - mod attr_prop_example; mod basic_test; mod container_kind_test; mod derive_test; From 607263f37eedb751ce559c369c49ab2d2426c15b Mon Sep 17 00:00:00 2001 From: wandalen Date: Tue, 28 May 2024 09:49:50 +0300 Subject: [PATCH 07/59] macro_tools : attr_props refactoring and examples --- module/core/former_meta/src/derive_former/field_attrs.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/module/core/former_meta/src/derive_former/field_attrs.rs b/module/core/former_meta/src/derive_former/field_attrs.rs index d9f46b6ac9..baedc773e2 100644 --- a/module/core/former_meta/src/derive_former/field_attrs.rs +++ b/module/core/former_meta/src/derive_former/field_attrs.rs @@ -508,8 +508,6 @@ impl syn::parse::Parse for AttributeSubformScalarSetter if lookahead.peek( syn::Ident ) { let ident : syn::Ident = input.parse()?; - - input.parse::< syn::Token![ = ] >()?; match ident.to_string().as_str() { AttributePropertyName::KEYWORD => result.assign( AttributePropertyName::parse( input )? ), From 74fd9d44289fe49816fd5504ffa5a9786688577c Mon Sep 17 00:00:00 2001 From: wandalen Date: Tue, 28 May 2024 16:57:00 +0300 Subject: [PATCH 08/59] macro_tools : evolve props --- module/core/derive_tools_meta/Cargo.toml | 5 +- .../core/derive_tools_meta/src/derive/from.rs | 278 ++-------- module/core/former_meta/Cargo.toml | 2 +- .../src/derive_former/field_attrs.rs | 55 -- .../src/derive_former/struct_attrs.rs | 1 + module/core/macro_tools/Readme.md | 10 +- .../examples/macro_tools_attr_prop.rs | 13 +- module/core/macro_tools/src/attr_prop.rs | 497 +----------------- .../core/macro_tools/src/attr_prop/boolean.rs | 176 +++++++ .../core/macro_tools/src/attr_prop/enabled.rs | 125 +++++ .../src/attr_prop/optional_boolean.rs | 89 ++++ .../macro_tools/src/attr_prop/optional_syn.rs | 132 +++++ module/core/macro_tools/src/attr_prop/syn.rs | 94 ++++ .../macro_tools/tests/inc/attr_prop_test.rs | 11 + 14 files changed, 724 insertions(+), 764 deletions(-) create mode 100644 module/core/macro_tools/src/attr_prop/boolean.rs create mode 100644 module/core/macro_tools/src/attr_prop/enabled.rs create mode 100644 module/core/macro_tools/src/attr_prop/optional_boolean.rs create mode 100644 module/core/macro_tools/src/attr_prop/optional_syn.rs create mode 100644 module/core/macro_tools/src/attr_prop/syn.rs diff --git a/module/core/derive_tools_meta/Cargo.toml b/module/core/derive_tools_meta/Cargo.toml index a229e5c66d..5d942547f4 100644 --- a/module/core/derive_tools_meta/Cargo.toml +++ b/module/core/derive_tools_meta/Cargo.toml @@ -63,7 +63,10 @@ derive_variadic_from = [] [dependencies] macro_tools = { workspace = true, features = [ "full" ] } iter_tools = { workspace = true, features = [ "full" ] } -# xxx : qqq : for Petro : optimize features set +former_types = { workspace = true, features = [ "enabled", "types_component_assign" ] } +const_format = { version = "0.2.32" } + +# xxx : qqq : optimize features set [dev-dependencies] test_tools = { workspace = true } diff --git a/module/core/derive_tools_meta/src/derive/from.rs b/module/core/derive_tools_meta/src/derive/from.rs index 2594f779d4..966cef9a6b 100644 --- a/module/core/derive_tools_meta/src/derive/from.rs +++ b/module/core/derive_tools_meta/src/derive/from.rs @@ -1,5 +1,19 @@ use super::*; -use macro_tools::{ attr, diag, generic_params, item_struct, struct_like::StructLike, Result }; +use macro_tools:: +{ + attr, + diag, + generic_params, + item_struct, + struct_like::StructLike, + Result, + AttributeComponent, + AttributePropertyComponent, + AttributePropertyBoolean, + // AttributePropertyEnabled, +}; + +use former_types::ComponentAssign; // xxx2 : get complete From for enums @@ -88,9 +102,9 @@ pub fn from( input : proc_macro::TokenStream ) -> Result< proc_macro2::TokenStre .or_insert( 1 ); }); - let variants = item.variants.iter().map( | variant | + let variants_result : Result< Vec< proc_macro2::TokenStream > > = item.variants.iter().map( | variant | { - if map[ &variant.fields.to_token_stream().to_string() ] <= 1 + if map[ & variant.fields.to_token_stream().to_string() ] <= 1 { variant_generate ( @@ -103,9 +117,12 @@ pub fn from( input : proc_macro::TokenStream ) -> Result< proc_macro2::TokenStre } else { - qt!{} + Ok( qt!{} ) } - }); + }).collect(); + + let variants = variants_result?; + qt! { #( #variants )* @@ -131,14 +148,20 @@ fn variant_generate generics_where: &syn::punctuated::Punctuated< syn::WherePredicate, syn::token::Comma >, variant : &syn::Variant, ) --> proc_macro2::TokenStream +-> Result< proc_macro2::TokenStream > { let variant_name = &variant.ident; let fields = &variant.fields; + let attrs = FieldAttributes::from_attrs( variant.attrs.iter() )?; + + if !attrs.config.enabled.value( true ) + { + return Ok( qt!{} ) + } if fields.len() <= 0 { - return qt!{} + return Ok( qt!{} ) } let ( args, use_src ) = if fields.len() == 1 @@ -163,20 +186,23 @@ fn variant_generate ) }; - qt! - { - #[ automatically_derived ] - impl< #generics_impl > From< #args > for #item_name< #generics_ty > - where - #generics_where + Ok + ( + qt! { - #[ inline ] - fn from( src : #args ) -> Self + #[ automatically_derived ] + impl< #generics_impl > From< #args > for #item_name< #generics_ty > + where + #generics_where { - Self::#variant_name( #use_src ) + #[ inline ] + fn from( src : #args ) -> Self + { + Self::#variant_name( #use_src ) + } } } - } + ) } @@ -357,28 +383,12 @@ fn generate_unit /// Attributes of a field / variant /// -// xxx -use macro_tools:: -{ - attr, - syn_err, - return_syn_err, - qt, - Result, - AttributeComponent, - AttributePropertyComponent, - AttributePropertyBoolean, - AttributePropertyEnabled, -}; - -use former_types::{ ComponentAssign }; - /// Represents the attributes of a struct. Aggregates all its attributes. #[ derive( Debug, Default ) ] pub struct FieldAttributes { /// Attribute for customizing the mutation process. - pub from : AttributeFrom, + pub config : AttributeFrom, } impl FieldAttributes @@ -470,6 +480,7 @@ impl FieldAttributes // } // // } +// xxx : clean #[ derive( Debug, Default ) ] pub struct AttributeFrom @@ -511,29 +522,29 @@ where #[ inline( always ) ] fn assign( &mut self, component : IntoT ) { - self.from = component.into(); + self.config = component.into(); } } -impl< IntoT > ComponentAssign< AttributePropertyHint, IntoT > for AttributeFrom +impl< IntoT > ComponentAssign< AttributePropertyEnabled, IntoT > for AttributeFrom where - IntoT : Into< AttributePropertyHint >, + IntoT : Into< AttributePropertyEnabled >, { #[ inline( always ) ] fn assign( &mut self, component : IntoT ) { - self.hint = component.into(); + self.enabled = component.into(); } } -impl< IntoT > ComponentAssign< AttributePropertyEnabled, IntoT > for AttributeFrom +impl< IntoT > ComponentAssign< AttributePropertyHint, IntoT > for AttributeFrom where - IntoT : Into< AttributePropertyEnabled >, + IntoT : Into< AttributePropertyHint >, { #[ inline( always ) ] fn assign( &mut self, component : IntoT ) { - self.custom = component.into(); + self.hint = component.into(); } } @@ -548,8 +559,9 @@ impl syn::parse::Parse for AttributeFrom let known = const_format::concatcp! ( "Known entries of attribute ", AttributeFrom::KEYWORD, " are : ", - AttributePropertyEnabled::KEYWORD, - ", ", AttributePropertyHint::KEYWORD, + AttributePropertyHint::KEYWORD, + ", ", AttributePropertyEnabled::KEYWORD_ON, + ", ", AttributePropertyEnabled::KEYWORD_OFF, ".", ); syn_err! @@ -569,10 +581,10 @@ impl syn::parse::Parse for AttributeFrom if lookahead.peek( syn::Ident ) { let ident : syn::Ident = input.parse()?; - match ident.to_string().as_str() { - AttributePropertyEnabled::KEYWORD => result.assign( AttributePropertyEnabled::parse( input )? ), + AttributePropertyEnabled::KEYWORD_ON => result.assign( AttributePropertyEnabled::from( true ) ), + AttributePropertyEnabled::KEYWORD_OFF => result.assign( AttributePropertyEnabled::from( false ) ), AttributePropertyHint::KEYWORD => result.assign( AttributePropertyHint::parse( input )? ), _ => return Err( error( &ident ) ), } @@ -616,180 +628,6 @@ pub type AttributePropertyHint = AttributePropertyBoolean< AttributePropertyHint #[ derive( Debug, Default, Clone, Copy ) ] pub struct AttributePropertyEnabledMarker; -impl AttributePropertyComponent for AttributePropertyEnabledMarker -{ - const KEYWORD : &'static str = "custom"; -} - /// Indicates whether a custom code should be generated. /// Defaults to `false`, meaning no custom code is generated unless explicitly requested. -pub type AttributePropertyEnabled = AttributePropertyEnabled< AttributePropertyEnabledMarker >; - -// pub struct FieldAttributes -// { -// pub from : Option< AttributeFrom >, -// } -// -// impl FieldAttributes -// { -// -// pub fn from_attrs< 'a >( attrs : impl Iterator< Item = &'a syn::Attribute > ) -> Result< Self > -// { -// let mut from : Option< AttributeFrom > = None; -// -// for attr in attrs -// { -// let key_ident = attr.path().get_ident() -// .ok_or_else( || syn_err!( attr, "Expects an attribute of format #[ attribute( key1 = val1, key2 = val2 ) ], but got:\n {}", qt!{ #attr } ) )?; -// let key_str = format!( "{}", key_ident ); -// -// if attr::is_standard( &key_str ) -// { -// continue; -// } -// -// // qqq : qqq for Anton : xxx : refactor field_attrs::FieldAttributes::from_attrs to make it similar to this function -// match key_str.as_ref() -// { -// AttributeFrom::KEYWORD => -// { -// from.replace( AttributeFrom::from_meta( attr )? ); -// } -// "debug" => -// { -// } -// _ => -// { -// return Err( syn_err!( attr, "Known field attirbutes are : `from`, `debug`.\nUnknown structure attribute : {}", qt!{ #attr } ) ); -// } -// } -// } -// -// Ok( FieldAttributes { from } ) -// } -// -// } -// -// -// /// -// /// Attribute to hold parameters of forming for a specific field or variant. -// /// For example to avoid code From generation for it. -// /// -// /// `#[ from( off, hint : true ) ]` -// /// -// -// #[ derive( Default ) ] -// pub struct AttributeFrom -// { -// /// Specifies whether we should generate From implementation for the field. -// /// Can be altered using `on` and `off` attributes -// pub enabled : Option< bool >, -// /// Specifies whether to provide a sketch of generated From or not. -// /// Defaults to `false`, which means no hint is provided unless explicitly requested. -// pub hint : bool, -// } -// -// impl AttributeFrom -// { -// -// const KEYWORD : &'static str = "from"; -// -// pub fn from_meta( attr : &syn::Attribute ) -> Result< Self > -// { -// match attr.meta -// { -// syn::Meta::List( ref meta_list ) => -// { -// return syn::parse2::< AttributeFrom >( meta_list.tokens.clone() ); -// }, -// syn::Meta::Path( ref _path ) => -// { -// return Ok( Default::default() ) -// }, -// _ => return_syn_err!( attr, "Expects an attribute of format #[ from( off ) ] -// .\nGot: {}", qt!{ #attr } ), -// } -// } -// -// } -// -// impl syn::parse::Parse for AttributeFrom -// { -// fn parse( input : syn::parse::ParseStream< '_ > ) -> syn::Result< Self > -// { -// let mut off : bool = false; -// let mut on : bool = false; -// let mut hint = false; -// -// while !input.is_empty() -// { -// let lookahead = input.lookahead1(); -// if lookahead.peek( syn::Ident ) -// { -// let ident : syn::Ident = input.parse()?; -// // xxx : qqq for Anton : use match here and for all attributes -- done -// match ident.to_string().as_str() -// { -// "off" => -// { -// input.parse::< syn::Token![ = ] >()?; -// let value : syn::LitBool = input.parse()?; -// off = value.value(); -// }, -// "on" => -// { -// input.parse::< syn::Token![ = ] >()?; -// let value : syn::LitBool = input.parse()?; -// on = value.value(); -// } -// "hint" => -// { -// input.parse::< syn::Token![ = ] >()?; -// let value : syn::LitBool = input.parse()?; -// hint = value.value; -// } -// _ => -// { -// return Err( syn::Error::new_spanned( &ident, format!( "Unexpected identifier '{}'. Expected 'on', 'off', or 'hint'. For example: `#[ from( off, hint : true ) ]`", ident ) ) ); -// } -// } -// } -// else -// { -// return Err( syn::Error::new( input.span(), "Unexpected identifier '{}'. Expected 'on', 'off', or 'hint'. For example: `#[ from( off, hint : true ) ]`" ) ); -// } -// -// } -// -// // xxx : move on / off logic into a helper -// -// let mut enabled : Option< bool > = None; -// -// if on && off -// { -// // return Err( syn_err!( input, "`on` and `off` are mutually exclusive .\nIllegal attribute usage : {}", qt!{ #input } ) ) -// return Err( syn::Error::new( input.span(), "`on` and `off` are mutually exclusive .\nIllegal attribute usage" ) ); -// // xxx : test -// } -// -// if !on && !off -// { -// enabled = None; -// } -// else if on -// { -// enabled = Some( true ) -// } -// else if off -// { -// enabled = Some( false ) -// } -// -// // Optional comma handling -// if input.peek( syn::Token![ , ] ) -// { -// input.parse::< syn::Token![ , ] >()?; -// } -// Ok( Self { enabled, hint } ) -// } -// } +pub type AttributePropertyEnabled = macro_tools::AttributePropertyEnabled< AttributePropertyEnabledMarker >; diff --git a/module/core/former_meta/Cargo.toml b/module/core/former_meta/Cargo.toml index 1ebe5ba608..8511f01c50 100644 --- a/module/core/former_meta/Cargo.toml +++ b/module/core/former_meta/Cargo.toml @@ -58,7 +58,7 @@ proc-macro = true [dependencies] macro_tools = { workspace = true } # qqq : optimize set of features -former_types = { workspace = true, features = [ "types_component_assign" ] } +former_types = { workspace = true, features = [ "enabled", "types_component_assign" ] } iter_tools = { workspace = true } convert_case = { version = "0.6.0", default-features = false, optional = true, features = [] } const_format = { version = "0.2.32" } diff --git a/module/core/former_meta/src/derive_former/field_attrs.rs b/module/core/former_meta/src/derive_former/field_attrs.rs index baedc773e2..5f2e86b719 100644 --- a/module/core/former_meta/src/derive_former/field_attrs.rs +++ b/module/core/former_meta/src/derive_former/field_attrs.rs @@ -532,61 +532,6 @@ impl syn::parse::Parse for AttributeSubformScalarSetter } } -// impl syn::parse::Parse for AttributeSubformScalarSetter -// { -// fn parse( input : syn::parse::ParseStream< '_ > ) -> syn::Result< Self > -// { -// let mut name : Option< syn::Ident > = None; -// let mut setter : Option< bool > = None; -// let mut hint = false; -// -// while !input.is_empty() -// { -// let lookahead = input.lookahead1(); -// if lookahead.peek( syn::Ident ) -// { -// let ident : syn::Ident = input.parse()?; -// match ident.to_string().as_str() -// { -// "name" => -// { -// input.parse::< syn::Token![ = ] >()?; -// name = Some( input.parse()? ); -// } -// "setter" => -// { -// input.parse::< syn::Token![ = ] >()?; -// let value : syn::LitBool = input.parse()?; -// setter = Some( value.value() ); -// } -// "hint" => -// { -// input.parse::< syn::Token![ = ] >()?; -// let value : syn::LitBool = input.parse()?; -// hint = value.value; -// } -// _ => -// { -// return Err( syn::Error::new_spanned( &ident, format!( "Unexpected identifier '{}'. Expected 'name', 'setter', or 'definition'. For example: `subform_scalar( name = myName, setter = true )`", ident ) ) ); -// } -// } -// } -// else -// { -// return Err( syn::Error::new( input.span(), "Expected 'name', 'setter', or 'definition' identifier. For example: `subform_scalar( name = myName, setter = true )`" ) ); -// } -// -// // Optional comma handling -// if input.peek( syn::Token![ , ] ) -// { -// input.parse::< syn::Token![ , ] >()?; -// } -// } -// -// Ok( Self { name : name.into(), setter : setter.into(), hint : hint.into() } ) -// } -// } - /// Represents an attribute for configuring collection 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. diff --git a/module/core/former_meta/src/derive_former/struct_attrs.rs b/module/core/former_meta/src/derive_former/struct_attrs.rs index 74ec9f39c7..be4f4f476e 100644 --- a/module/core/former_meta/src/derive_former/struct_attrs.rs +++ b/module/core/former_meta/src/derive_former/struct_attrs.rs @@ -286,6 +286,7 @@ pub struct AttributeMutator /// Specifies whether to provide a sketch of the mutator as a hint. /// Defaults to `false`, which means no hint is provided unless explicitly requested. pub hint : AttributePropertyHint, + // qqq : xxx : use the property. currently it's not used } impl AttributeComponent for AttributeMutator diff --git a/module/core/macro_tools/Readme.md b/module/core/macro_tools/Readme.md index 1add7411f8..7048a69611 100644 --- a/module/core/macro_tools/Readme.md +++ b/module/core/macro_tools/Readme.md @@ -88,8 +88,14 @@ fn main() use macro_tools:: { - attr, syn_err, return_syn_err, qt, Result, AttributeComponent, - AttributePropertyComponent, AttributePropertyBoolean, + attr, + syn_err, + return_syn_err, + qt, + Result, + AttributeComponent, + AttributePropertyComponent, + AttributePropertyBoolean, }; use former_types::ComponentAssign; diff --git a/module/core/macro_tools/examples/macro_tools_attr_prop.rs b/module/core/macro_tools/examples/macro_tools_attr_prop.rs index 1ae5caa3eb..31faaaedf3 100644 --- a/module/core/macro_tools/examples/macro_tools_attr_prop.rs +++ b/module/core/macro_tools/examples/macro_tools_attr_prop.rs @@ -34,8 +34,14 @@ fn main() use macro_tools:: { - attr, syn_err, return_syn_err, qt, Result, AttributeComponent, - AttributePropertyComponent, AttributePropertyBoolean, + attr, + syn_err, + return_syn_err, + qt, + Result, + AttributeComponent, + AttributePropertyComponent, + AttributePropertyBoolean, }; use former_types::ComponentAssign; @@ -264,7 +270,7 @@ fn main() /// Defaults to `false`, meaning no custom code is generated unless explicitly requested. pub type AttributePropertyCustom = AttributePropertyBoolean< AttributePropertyCustomMarker >; - // == Test code + // == test code // Parse an attribute and construct a `StructAttributes` instance. let input : syn::Attribute = syn::parse_quote!( #[ mutator( custom = true, hint = false ) ] ); @@ -278,4 +284,5 @@ fn main() assert_eq!( attr.internal(), true ); let attr : AttributePropertyBoolean< AttributePropertyHintMarker > = false.into(); assert_eq!( attr.internal(), false ); + } diff --git a/module/core/macro_tools/src/attr_prop.rs b/module/core/macro_tools/src/attr_prop.rs index f75491dae1..8b3b3e0f51 100644 --- a/module/core/macro_tools/src/attr_prop.rs +++ b/module/core/macro_tools/src/attr_prop.rs @@ -95,485 +95,16 @@ //! The `parse_quote!` macro is used to create a `syn::Attribute` instance with the attribute syntax, //! which is then parsed into the `MyAttributes` struct. The resulting `MyAttributes` instance is printed to the console. +mod enabled; +mod boolean; +mod optional_boolean; +mod syn; +mod optional_syn; + /// Internal namespace. pub( crate ) mod private { - use crate::*; - - // = AttributePropertyBoolean - - /// A generic boolean attribute property. - /// Defaults to `false`. - /// - /// # Example - /// - /// ```rust - /// use macro_tools::AttributePropertyBoolean; - /// - /// #[ derive( Debug, Default, Clone, Copy ) ] - /// pub struct DebugMarker; - /// - /// #[ derive( Debug, Default, Clone, Copy ) ] - /// pub struct EnabledMarker; - /// - /// pub trait AttributePropertyComponent - /// { - /// const KEYWORD : &'static str; - /// } - /// - /// impl AttributePropertyComponent for DebugMarker - /// { - /// const KEYWORD : &'static str = "debug"; - /// } - /// - /// impl AttributePropertyComponent for EnabledMarker - /// { - /// const KEYWORD : &'static str = "enabled"; - /// } - /// - /// #[ derive( Debug, Default ) ] - /// struct MyAttributes - /// { - /// pub debug : AttributePropertyBoolean< DebugMarker >, - /// pub enabled : AttributePropertyBoolean< EnabledMarker >, - /// } - /// - /// impl syn::parse::Parse for MyAttributes - /// { - /// fn parse( input : syn::parse::ParseStream< '_ > ) -> syn::Result< Self > - /// { - /// let mut debug = AttributePropertyBoolean::< DebugMarker >::default(); - /// let mut enabled = AttributePropertyBoolean::< EnabledMarker >::default(); - /// - /// while !input.is_empty() - /// { - /// let lookahead = input.lookahead1(); - /// if lookahead.peek( syn::Ident ) - /// { - /// let ident : syn::Ident = input.parse()?; - /// match ident.to_string().as_str() - /// { - /// DebugMarker::KEYWORD => debug = input.parse()?, - /// EnabledMarker::KEYWORD => enabled = input.parse()?, - /// _ => return Err( lookahead.error() ), - /// } - /// } - /// else - /// { - /// return Err( lookahead.error() ); - /// } - /// - /// // Optional comma handling - /// if input.peek( syn::Token![,] ) - /// { - /// input.parse::< syn::Token![,] >()?; - /// } - /// } - /// - /// Ok( MyAttributes { debug, enabled } ) - /// } - /// } - /// - /// let input : syn::Attribute = syn::parse_quote!( #[ attribute( enabled = true, debug = false ) ] ); - /// let meta = match input.meta - /// { - /// syn::Meta::List( meta_list ) => meta_list, - /// _ => panic!( "Expected a Meta::List" ), - /// }; - /// - /// let nested_meta_stream : proc_macro2::TokenStream = meta.tokens; - /// let attrs : MyAttributes = syn::parse2( nested_meta_stream ).unwrap(); - /// println!( "{:?}", attrs ); - /// ``` - /// - /// In this example, the `AttributePropertyBoolean` struct is used to define attributes with boolean properties. - /// The `DebugMarker` and `EnabledMarker` structs act as markers to distinguish between different boolean attributes. - /// The `MyAttributes` struct aggregates these boolean attributes. - /// - /// The `Parse` implementation for `MyAttributes` iterates through the attribute's key-value pairs, - /// identifying each by its marker's keyword and parsing the boolean value. - /// It uses the `ParseStream` to parse identifiers and their associated values, - /// matching them to the appropriate marker's keyword. - /// If an unrecognized identifier is encountered, it returns an error. - /// - /// The `parse_quote!` macro is used to create a `syn::Attribute` instance with the attribute syntax, - /// which is then parsed into the `MyAttributes` struct. The resulting `MyAttributes` instance is printed to the console. - - #[ derive( Debug, Default, Clone, Copy ) ] - pub struct AttributePropertyBoolean< Marker >( bool, ::core::marker::PhantomData< Marker > ); - - impl< Marker > AttributePropertyBoolean< Marker > - { - /// Just unwraps and returns the internal data. - pub fn internal( self ) -> bool - { - self.0 - } - - /// Returns a reference to the internal boolean value. - pub fn ref_internal( &self ) -> &bool - { - &self.0 - } - } - - impl< Marker > AttributePropertyComponent for AttributePropertyBoolean< Marker > - where - Marker : AttributePropertyComponent, - { - const KEYWORD : &'static str = Marker::KEYWORD; - } - - impl< Marker > syn::parse::Parse for AttributePropertyBoolean< Marker > - { - fn parse( input : syn::parse::ParseStream< '_ > ) -> syn::Result< Self > - { - input.parse::< syn::Token![ = ] >()?; - let value : syn::LitBool = input.parse()?; - Ok( value.value.into() ) - } - } - - impl< Marker > From< bool > for AttributePropertyBoolean< Marker > - { - #[ inline( always ) ] - fn from( src : bool ) -> Self - { - Self( src, Default::default() ) - } - } - - impl< Marker > From< AttributePropertyBoolean< Marker > > for bool - { - #[ inline( always ) ] - fn from( src : AttributePropertyBoolean< Marker > ) -> Self - { - src.0 - } - } - - impl< Marker > core::ops::Deref for AttributePropertyBoolean< Marker > - { - type Target = bool; - - #[ inline( always ) ] - fn deref( &self ) -> &bool - { - &self.0 - } - } - - impl< Marker > AsRef< bool > for AttributePropertyBoolean< Marker > - { - #[ inline( always ) ] - fn as_ref( &self ) -> &bool - { - &self.0 - } - } - - // = AttributePropertyOptionalBoolean - - /// A generic optional boolean attribute property: `Option< bool >`. - /// Defaults to `false`. - #[ derive( Debug, Default, Clone, Copy ) ] - pub struct AttributePropertyOptionalBoolean< Marker >( Option< bool >, ::core::marker::PhantomData< Marker > ); - - impl< Marker > AttributePropertyOptionalBoolean< Marker > - { - /// Just unwraps and returns the internal data. - pub fn internal( self ) -> Option< bool > - { - self.0 - } - - /// Returns a reference to the internal optional boolean value. - pub fn ref_internal( &self ) -> Option< &bool > - { - self.0.as_ref() - } - } - - impl< Marker > AttributePropertyComponent for AttributePropertyOptionalBoolean< Marker > - where - Marker : AttributePropertyComponent, - { - const KEYWORD : &'static str = Marker::KEYWORD; - } - - impl< Marker > syn::parse::Parse for AttributePropertyOptionalBoolean< Marker > - { - fn parse( input : syn::parse::ParseStream< '_ > ) -> syn::Result< Self > - { - input.parse::< syn::Token![ = ] >()?; - let value : syn::LitBool = input.parse()?; - Ok( value.value.into() ) - } - } - - impl< Marker > From< bool > for AttributePropertyOptionalBoolean< Marker > - { - #[ inline( always ) ] - fn from( src : bool ) -> Self - { - Self( Some( src ), Default::default() ) - } - } - - impl< Marker > From< Option< bool > > for AttributePropertyOptionalBoolean< Marker > - { - #[ inline( always ) ] - fn from( src : Option< bool > ) -> Self - { - Self( src, Default::default() ) - } - } - - impl< Marker > From< AttributePropertyOptionalBoolean< Marker > > for Option< bool > - { - #[ inline( always ) ] - fn from( src : AttributePropertyOptionalBoolean< Marker > ) -> Self - { - src.0 - } - } - - impl< Marker > core::ops::Deref for AttributePropertyOptionalBoolean< Marker > - { - type Target = Option< bool >; - #[ inline( always ) ] - fn deref( &self ) -> &Option< bool > - { - &self.0 - } - } - - impl< Marker > AsRef< Option< bool > > for AttributePropertyOptionalBoolean< Marker > - { - #[ inline( always ) ] - fn as_ref( &self ) -> &Option< bool > - { - &self.0 - } - } - - // = AttributePropertySyn - - /// - /// Property of an attribute which simply wraps one of the standard `syn` types. - /// - #[ derive( Debug, Clone ) ] - pub struct AttributePropertySyn< T, Marker >( T, ::core::marker::PhantomData< Marker > ) - where - T : syn::parse::Parse + quote::ToTokens; - - impl< T, Marker > AttributePropertySyn< T, Marker > - where - T : syn::parse::Parse + quote::ToTokens, - { - /// Just unwraps and returns the internal data. - #[ allow( dead_code ) ] - pub fn internal( self ) -> T - { - self.0 - } - - /// Returns a reference to the internal data. - #[ allow( dead_code ) ] - pub fn ref_internal( &self ) -> &T - { - &self.0 - } - } - - impl< T, Marker > AttributePropertyComponent for AttributePropertySyn< T, Marker > - where - T : syn::parse::Parse + quote::ToTokens, - Marker : AttributePropertyComponent, - { - const KEYWORD : &'static str = Marker::KEYWORD; - } - - impl< T, Marker > syn::parse::Parse for AttributePropertySyn< T, Marker > - where - T : syn::parse::Parse + quote::ToTokens, - { - fn parse( input : syn::parse::ParseStream< '_ > ) -> syn::Result< Self > - { - input.parse::< syn::Token![ = ] >()?; - let value : T = input.parse()?; - Ok( value.into() ) - } - } - - impl< T, Marker > quote::ToTokens for AttributePropertySyn< T, Marker > - where - T : syn::parse::Parse + quote::ToTokens, - { - fn to_tokens( &self, tokens : &mut proc_macro2::TokenStream ) - { - self.0.to_tokens( tokens ); - } - } - - impl< T, Marker > core::ops::Deref for AttributePropertySyn< T, Marker > - where T : syn::parse::Parse + quote::ToTokens - { - type Target = T; - #[ inline( always ) ] - fn deref( &self ) -> &T - { - &self.0 - } - } - - impl< T, Marker > AsRef< T > for AttributePropertySyn< T, Marker > - where T : syn::parse::Parse + quote::ToTokens - { - #[ inline( always ) ] - fn as_ref( &self ) -> &T - { - &self.0 - } - } - - impl< T, Marker > From< T > for AttributePropertySyn< T, Marker > - where T : syn::parse::Parse + quote::ToTokens - { - #[ inline( always ) ] - fn from( src : T ) -> Self - { - Self( src, Default::default() ) - } - } - - // = AttributePropertyOptionalSyn - - /// - /// Property of an attribute which simply wraps one of the standard `syn` types and keeps it optional. - /// - #[ derive( Debug, Clone ) ] - pub struct AttributePropertyOptionalSyn< T, Marker >( Option< T >, ::core::marker::PhantomData< Marker > ) - where - T : syn::parse::Parse + quote::ToTokens; - - impl< T, Marker > AttributePropertyOptionalSyn< T, Marker > - where - T : syn::parse::Parse + quote::ToTokens, - { - /// Just unwraps and returns the internal data. - pub fn internal( self ) -> Option< T > - { - self.0 - } - - /// Returns an Option reference to the internal data. - pub fn ref_internal( &self ) -> Option< &T > - { - self.0.as_ref() - } - } - - impl< T, Marker > AttributePropertyComponent for AttributePropertyOptionalSyn< T, Marker > - where - T : syn::parse::Parse + quote::ToTokens, - Marker : AttributePropertyComponent, - { - const KEYWORD : &'static str = Marker::KEYWORD; - } - - impl< T, Marker > Default for AttributePropertyOptionalSyn< T, Marker > - where - T : syn::parse::Parse + quote::ToTokens, - { - fn default() -> Self - { - Self( None, Default::default() ) - } - } - - impl< T, Marker > syn::parse::Parse for AttributePropertyOptionalSyn< T, Marker > - where - T : syn::parse::Parse + quote::ToTokens, - { - fn parse( input : syn::parse::ParseStream< '_ > ) -> syn::Result< Self > - { - input.parse::< syn::Token![ = ] >()?; - let value : T = input.parse()?; - Ok( value.into() ) - } - } - - impl< T, Marker > quote::ToTokens for AttributePropertyOptionalSyn< T, Marker > - where - T : syn::parse::Parse + quote::ToTokens, - { - fn to_tokens( &self, tokens : &mut proc_macro2::TokenStream ) - { - self.0.to_tokens( tokens ); - } - } - - impl< T, Marker > core::ops::Deref for AttributePropertyOptionalSyn< T, Marker > - where T : syn::parse::Parse + quote::ToTokens - { - type Target = Option< T >; - #[ inline( always ) ] - fn deref( &self ) -> &Option< T > - { - &self.0 - } - } - - impl< T, Marker > AsRef< Option< T > > for AttributePropertyOptionalSyn< T, Marker > - where T : syn::parse::Parse + quote::ToTokens - { - #[ inline( always ) ] - fn as_ref( &self ) -> &Option< T > - { - &self.0 - } - } - - impl< T, Marker > From< T > for AttributePropertyOptionalSyn< T, Marker > - where T : syn::parse::Parse + quote::ToTokens - { - #[ inline( always ) ] - fn from( src : T ) -> Self - { - Self( Some( src ), Default::default() ) - } - } - - impl< T, Marker > From< Option< T > > for AttributePropertyOptionalSyn< T, Marker > - where T : syn::parse::Parse + quote::ToTokens - { - #[ inline( always ) ] - fn from( src : Option< T > ) -> Self - { - Self( src, Default::default() ) - } - } - - impl< T, Marker > From< AttributePropertyOptionalSyn< T, Marker > > for Option< T > - where T : syn::parse::Parse + quote::ToTokens - { - #[ inline( always ) ] - fn from( src : AttributePropertyOptionalSyn< T, Marker > ) -> Self - { - src.0 - } - } - - impl< 'a, T, Marker > From< &'a AttributePropertyOptionalSyn< T, Marker > > for Option< &'a T > - where T : syn::parse::Parse + quote::ToTokens - { - #[ inline( always ) ] - fn from( src : &'a AttributePropertyOptionalSyn< T, Marker > ) -> Self - { - src.0.as_ref() - } - } + // use crate::*; } @@ -611,12 +142,14 @@ pub mod exposed pub use super::prelude::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::private:: - { - AttributePropertyBoolean, - AttributePropertyOptionalBoolean, - AttributePropertySyn, - AttributePropertyOptionalSyn, + pub use super:: + { + enabled::AttributePropertyEnabled, + enabled::AttributePropertyEnabledMarker, + boolean::AttributePropertyBoolean, + optional_boolean::AttributePropertyOptionalBoolean, + syn::AttributePropertySyn, + optional_syn::AttributePropertyOptionalSyn, }; } diff --git a/module/core/macro_tools/src/attr_prop/boolean.rs b/module/core/macro_tools/src/attr_prop/boolean.rs new file mode 100644 index 0000000000..dfa1c80fde --- /dev/null +++ b/module/core/macro_tools/src/attr_prop/boolean.rs @@ -0,0 +1,176 @@ +//! +//! A generic boolean attribute property. +//! Defaults to `false`. +//! + +use crate::*; + +/// A generic boolean attribute property. +/// Defaults to `false`. +/// +/// # Example +/// +/// ```rust +/// use macro_tools::AttributePropertyBoolean; +/// +/// #[ derive( Debug, Default, Clone, Copy ) ] +/// pub struct DebugMarker; +/// +/// #[ derive( Debug, Default, Clone, Copy ) ] +/// pub struct EnabledMarker; +/// +/// pub trait AttributePropertyComponent +/// { +/// const KEYWORD : &'static str; +/// } +/// +/// impl AttributePropertyComponent for DebugMarker +/// { +/// const KEYWORD : &'static str = "debug"; +/// } +/// +/// impl AttributePropertyComponent for EnabledMarker +/// { +/// const KEYWORD : &'static str = "enabled"; +/// } +/// +/// #[ derive( Debug, Default ) ] +/// struct MyAttributes +/// { +/// pub debug : AttributePropertyBoolean< DebugMarker >, +/// pub enabled : AttributePropertyBoolean< EnabledMarker >, +/// } +/// +/// impl syn::parse::Parse for MyAttributes +/// { +/// fn parse( input : syn::parse::ParseStream< '_ > ) -> syn::Result< Self > +/// { +/// let mut debug = AttributePropertyBoolean::< DebugMarker >::default(); +/// let mut enabled = AttributePropertyBoolean::< EnabledMarker >::default(); +/// +/// while !input.is_empty() +/// { +/// let lookahead = input.lookahead1(); +/// if lookahead.peek( syn::Ident ) +/// { +/// let ident : syn::Ident = input.parse()?; +/// match ident.to_string().as_str() +/// { +/// DebugMarker::KEYWORD => debug = input.parse()?, +/// EnabledMarker::KEYWORD => enabled = input.parse()?, +/// _ => return Err( lookahead.error() ), +/// } +/// } +/// else +/// { +/// return Err( lookahead.error() ); +/// } +/// +/// // Optional comma handling +/// if input.peek( syn::Token![,] ) +/// { +/// input.parse::< syn::Token![,] >()?; +/// } +/// } +/// +/// Ok( MyAttributes { debug, enabled } ) +/// } +/// } +/// +/// let input : syn::Attribute = syn::parse_quote!( #[ attribute( enabled = true, debug = false ) ] ); +/// let meta = match input.meta +/// { +/// syn::Meta::List( meta_list ) => meta_list, +/// _ => panic!( "Expected a Meta::List" ), +/// }; +/// +/// let nested_meta_stream : proc_macro2::TokenStream = meta.tokens; +/// let attrs : MyAttributes = syn::parse2( nested_meta_stream ).unwrap(); +/// println!( "{:?}", attrs ); +/// ``` +/// +/// In this example, the `AttributePropertyBoolean` struct is used to define attributes with boolean properties. +/// The `DebugMarker` and `EnabledMarker` structs act as markers to distinguish between different boolean attributes. +/// The `MyAttributes` struct aggregates these boolean attributes. +/// +/// The `Parse` implementation for `MyAttributes` iterates through the attribute's key-value pairs, +/// identifying each by its marker's keyword and parsing the boolean value. +/// It uses the `ParseStream` to parse identifiers and their associated values, +/// matching them to the appropriate marker's keyword. +/// If an unrecognized identifier is encountered, it returns an error. +/// +/// The `parse_quote!` macro is used to create a `syn::Attribute` instance with the attribute syntax, +/// which is then parsed into the `MyAttributes` struct. The resulting `MyAttributes` instance is printed to the console. + +#[ derive( Debug, Default, Clone, Copy ) ] +pub struct AttributePropertyBoolean< Marker >( bool, ::core::marker::PhantomData< Marker > ); + +impl< Marker > AttributePropertyBoolean< Marker > +{ + /// Just unwraps and returns the internal data. + pub fn internal( self ) -> bool + { + self.0 + } + + /// Returns a reference to the internal boolean value. + pub fn ref_internal( &self ) -> &bool + { + &self.0 + } +} + +impl< Marker > AttributePropertyComponent for AttributePropertyBoolean< Marker > +where + Marker : AttributePropertyComponent, +{ + const KEYWORD : &'static str = Marker::KEYWORD; +} + +impl< Marker > syn::parse::Parse for AttributePropertyBoolean< Marker > +{ + fn parse( input : syn::parse::ParseStream< '_ > ) -> syn::Result< Self > + { + input.parse::< syn::Token![ = ] >()?; + let value : syn::LitBool = input.parse()?; + Ok( value.value.into() ) + } +} + +impl< Marker > From< bool > for AttributePropertyBoolean< Marker > +{ + #[ inline( always ) ] + fn from( src : bool ) -> Self + { + Self( src, Default::default() ) + } +} + +impl< Marker > From< AttributePropertyBoolean< Marker > > for bool +{ + #[ inline( always ) ] + fn from( src : AttributePropertyBoolean< Marker > ) -> Self + { + src.0 + } +} + +impl< Marker > core::ops::Deref for AttributePropertyBoolean< Marker > +{ + type Target = bool; + + #[ inline( always ) ] + fn deref( &self ) -> &bool + { + &self.0 + } +} + +impl< Marker > AsRef< bool > for AttributePropertyBoolean< Marker > +{ + #[ inline( always ) ] + fn as_ref( &self ) -> &bool + { + &self.0 + } +} diff --git a/module/core/macro_tools/src/attr_prop/enabled.rs b/module/core/macro_tools/src/attr_prop/enabled.rs new file mode 100644 index 0000000000..96312093f4 --- /dev/null +++ b/module/core/macro_tools/src/attr_prop/enabled.rs @@ -0,0 +1,125 @@ +//! A generic boolean attribute property. +//! Defaults to `None`. +//! +//! This property can have three states: `None`, `Some(true)`, or `Some(false)`. +//! It parses `on` and `off` keywords to represent `Some(true)` and `Some(false)` respectively. +//! +//! # Example +//! +//! ```ignore +//! #[ attribute( on) ] +//! #[ attribute( off ) ] +//! ``` +//! +//! This is useful for attributes that need to enable or disable features or flags. + +use crate::*; + +/// Default marker for `AttributePropertyEnabled`. +#[ derive( Debug, Default, Clone, Copy ) ] +pub struct AttributePropertyEnabledMarker; + +/// A generic attribute property for switching on/off. +/// Has 3 states: `None`, `Some( true )`, `Some( false )`. +/// Defaults to `None`. +/// +/// Unlike [`AttributePropertyOptionalBoolean`], it "understands" `on`, `off` keywords during parsing. +/// For example: `#[ attribute( on ) ]` and `#[ attribute( off )]`. +/// As a consequence, the property has two keywords. +#[ derive( Debug, Default, Clone, Copy ) ] +pub struct AttributePropertyEnabled< Marker = AttributePropertyEnabledMarker > +( + Option< bool >, + ::core::marker::PhantomData< Marker > +); + +impl< Marker > AttributePropertyEnabled< Marker > +{ + /// Keywords for parsing this attribute property. + pub const KEYWORDS : [& 'static str ; 2] = [ "on", "off" ]; + /// Keywords for parsing this attribute property. + pub const KEYWORD_OFF : & 'static str = "off"; + /// Keywords for parsing this attribute property. + pub const KEYWORD_ON : & 'static str = "on"; + + /// Return bool value: on/off, use argument as default if it's `None`. + #[ inline ] + pub fn value( self, default : bool ) -> bool + { + if self.0.is_none() + { + return default; + } + self.0.unwrap() + } + +} + +impl< Marker > AttributePropertyEnabled< Marker > +{ + /// Unwraps and returns the internal optional boolean value. + pub fn internal( self ) -> Option< bool > + { + self.0 + } + + /// Returns a reference to the internal optional boolean value. + pub fn ref_internal( & self ) -> Option< & bool > + { + self.0.as_ref() + } +} + +impl< Marker > AttributePropertyComponent for AttributePropertyEnabled< Marker > +where + Marker : AttributePropertyComponent, +{ + const KEYWORD : & 'static str = Marker::KEYWORD; +} + +impl< Marker > From< bool > for AttributePropertyEnabled< Marker > +{ + #[ inline( always ) ] + fn from( src : bool ) -> Self + { + Self( Some( src ), Default::default() ) + } +} + +impl< Marker > From< Option< bool > > for AttributePropertyEnabled< Marker > +{ + #[ inline( always ) ] + fn from( src : Option< bool > ) -> Self + { + Self( src, Default::default() ) + } +} + +impl< Marker > From< AttributePropertyEnabled< Marker > > for Option< bool > +{ + #[ inline( always ) ] + fn from( src : AttributePropertyEnabled< Marker > ) -> Self + { + src.0 + } +} + +impl< Marker > core::ops::Deref for AttributePropertyEnabled< Marker > +{ + type Target = Option< bool >; + + #[ inline( always ) ] + fn deref( & self ) -> & Option< bool > + { + & self.0 + } +} + +impl< Marker > AsRef< Option< bool > > for AttributePropertyEnabled< Marker > +{ + #[ inline( always ) ] + fn as_ref( & self ) -> & Option< bool > + { + & self.0 + } +} diff --git a/module/core/macro_tools/src/attr_prop/optional_boolean.rs b/module/core/macro_tools/src/attr_prop/optional_boolean.rs new file mode 100644 index 0000000000..f1111360b1 --- /dev/null +++ b/module/core/macro_tools/src/attr_prop/optional_boolean.rs @@ -0,0 +1,89 @@ +//! +//! A generic optional boolean attribute property: `Option< bool >`. +//! Defaults to `false`. +//! + +use crate::*; + +/// A generic optional boolean attribute property: `Option< bool >`. +/// Defaults to `false`. +#[ derive( Debug, Default, Clone, Copy ) ] +pub struct AttributePropertyOptionalBoolean< Marker >( Option< bool >, ::core::marker::PhantomData< Marker > ); + +impl< Marker > AttributePropertyOptionalBoolean< Marker > +{ + /// Just unwraps and returns the internal data. + pub fn internal( self ) -> Option< bool > + { + self.0 + } + + /// Returns a reference to the internal optional boolean value. + pub fn ref_internal( &self ) -> Option< &bool > + { + self.0.as_ref() + } +} + +impl< Marker > AttributePropertyComponent for AttributePropertyOptionalBoolean< Marker > +where + Marker : AttributePropertyComponent, +{ + const KEYWORD : &'static str = Marker::KEYWORD; +} + +impl< Marker > syn::parse::Parse for AttributePropertyOptionalBoolean< Marker > +{ + fn parse( input : syn::parse::ParseStream< '_ > ) -> syn::Result< Self > + { + input.parse::< syn::Token![ = ] >()?; + let value : syn::LitBool = input.parse()?; + Ok( value.value.into() ) + } +} + +impl< Marker > From< bool > for AttributePropertyOptionalBoolean< Marker > +{ + #[ inline( always ) ] + fn from( src : bool ) -> Self + { + Self( Some( src ), Default::default() ) + } +} + +impl< Marker > From< Option< bool > > for AttributePropertyOptionalBoolean< Marker > +{ + #[ inline( always ) ] + fn from( src : Option< bool > ) -> Self + { + Self( src, Default::default() ) + } +} + +impl< Marker > From< AttributePropertyOptionalBoolean< Marker > > for Option< bool > +{ + #[ inline( always ) ] + fn from( src : AttributePropertyOptionalBoolean< Marker > ) -> Self + { + src.0 + } +} + +impl< Marker > core::ops::Deref for AttributePropertyOptionalBoolean< Marker > +{ + type Target = Option< bool >; + #[ inline( always ) ] + fn deref( &self ) -> &Option< bool > + { + &self.0 + } +} + +impl< Marker > AsRef< Option< bool > > for AttributePropertyOptionalBoolean< Marker > +{ + #[ inline( always ) ] + fn as_ref( &self ) -> &Option< bool > + { + &self.0 + } +} diff --git a/module/core/macro_tools/src/attr_prop/optional_syn.rs b/module/core/macro_tools/src/attr_prop/optional_syn.rs new file mode 100644 index 0000000000..2dc4d8e0c9 --- /dev/null +++ b/module/core/macro_tools/src/attr_prop/optional_syn.rs @@ -0,0 +1,132 @@ +//! +//! Property of an attribute which simply wraps one of the standard `syn` types and keeps it optional. +//! + +use crate::*; + +/// +/// Property of an attribute which simply wraps one of the standard `syn` types and keeps it optional. +/// + +#[ derive( Debug, Clone ) ] +pub struct AttributePropertyOptionalSyn< T, Marker >( Option< T >, ::core::marker::PhantomData< Marker > ) +where + T : syn::parse::Parse + quote::ToTokens; + +impl< T, Marker > AttributePropertyOptionalSyn< T, Marker > +where + T : syn::parse::Parse + quote::ToTokens, +{ + /// Just unwraps and returns the internal data. + pub fn internal( self ) -> Option< T > + { + self.0 + } + + /// Returns an Option reference to the internal data. + pub fn ref_internal( &self ) -> Option< &T > + { + self.0.as_ref() + } +} + +impl< T, Marker > AttributePropertyComponent for AttributePropertyOptionalSyn< T, Marker > +where + T : syn::parse::Parse + quote::ToTokens, + Marker : AttributePropertyComponent, +{ + const KEYWORD : &'static str = Marker::KEYWORD; +} + +impl< T, Marker > Default for AttributePropertyOptionalSyn< T, Marker > +where + T : syn::parse::Parse + quote::ToTokens, +{ + fn default() -> Self + { + Self( None, Default::default() ) + } +} + +impl< T, Marker > syn::parse::Parse for AttributePropertyOptionalSyn< T, Marker > +where + T : syn::parse::Parse + quote::ToTokens, +{ + fn parse( input : syn::parse::ParseStream< '_ > ) -> syn::Result< Self > + { + input.parse::< syn::Token![ = ] >()?; + let value : T = input.parse()?; + Ok( value.into() ) + } +} + +impl< T, Marker > quote::ToTokens for AttributePropertyOptionalSyn< T, Marker > +where + T : syn::parse::Parse + quote::ToTokens, +{ + fn to_tokens( &self, tokens : &mut proc_macro2::TokenStream ) + { + self.0.to_tokens( tokens ); + } +} + +impl< T, Marker > core::ops::Deref for AttributePropertyOptionalSyn< T, Marker > +where T : syn::parse::Parse + quote::ToTokens +{ + type Target = Option< T >; + #[ inline( always ) ] + fn deref( &self ) -> &Option< T > + { + &self.0 + } +} + +impl< T, Marker > AsRef< Option< T > > for AttributePropertyOptionalSyn< T, Marker > +where T : syn::parse::Parse + quote::ToTokens +{ + #[ inline( always ) ] + fn as_ref( &self ) -> &Option< T > + { + &self.0 + } +} + +impl< T, Marker > From< T > for AttributePropertyOptionalSyn< T, Marker > +where T : syn::parse::Parse + quote::ToTokens +{ + #[ inline( always ) ] + fn from( src : T ) -> Self + { + Self( Some( src ), Default::default() ) + } +} + +impl< T, Marker > From< Option< T > > for AttributePropertyOptionalSyn< T, Marker > +where T : syn::parse::Parse + quote::ToTokens +{ + #[ inline( always ) ] + fn from( src : Option< T > ) -> Self + { + Self( src, Default::default() ) + } +} + +impl< T, Marker > From< AttributePropertyOptionalSyn< T, Marker > > for Option< T > +where T : syn::parse::Parse + quote::ToTokens +{ + #[ inline( always ) ] + fn from( src : AttributePropertyOptionalSyn< T, Marker > ) -> Self + { + src.0 + } +} + +impl< 'a, T, Marker > From< &'a AttributePropertyOptionalSyn< T, Marker > > for Option< &'a T > +where T : syn::parse::Parse + quote::ToTokens +{ + #[ inline( always ) ] + fn from( src : &'a AttributePropertyOptionalSyn< T, Marker > ) -> Self + { + src.0.as_ref() + } +} diff --git a/module/core/macro_tools/src/attr_prop/syn.rs b/module/core/macro_tools/src/attr_prop/syn.rs new file mode 100644 index 0000000000..abd21fea38 --- /dev/null +++ b/module/core/macro_tools/src/attr_prop/syn.rs @@ -0,0 +1,94 @@ +//! +//! Property of an attribute which simply wraps one of the standard `syn` types. +//! + +use crate::*; + +/// +/// Property of an attribute which simply wraps one of the standard `syn` types. +/// + +#[ derive( Debug, Clone ) ] +pub struct AttributePropertySyn< T, Marker >( T, ::core::marker::PhantomData< Marker > ) +where + T : syn::parse::Parse + quote::ToTokens; + +impl< T, Marker > AttributePropertySyn< T, Marker > +where + T : syn::parse::Parse + quote::ToTokens, +{ + /// Just unwraps and returns the internal data. + #[ allow( dead_code ) ] + pub fn internal( self ) -> T + { + self.0 + } + + /// Returns a reference to the internal data. + #[ allow( dead_code ) ] + pub fn ref_internal( &self ) -> &T + { + &self.0 + } +} + +impl< T, Marker > AttributePropertyComponent for AttributePropertySyn< T, Marker > +where + T : syn::parse::Parse + quote::ToTokens, + Marker : AttributePropertyComponent, +{ + const KEYWORD : &'static str = Marker::KEYWORD; +} + +impl< T, Marker > syn::parse::Parse for AttributePropertySyn< T, Marker > +where + T : syn::parse::Parse + quote::ToTokens, +{ + fn parse( input : syn::parse::ParseStream< '_ > ) -> syn::Result< Self > + { + input.parse::< syn::Token![ = ] >()?; + let value : T = input.parse()?; + Ok( value.into() ) + } +} + +impl< T, Marker > quote::ToTokens for AttributePropertySyn< T, Marker > +where + T : syn::parse::Parse + quote::ToTokens, +{ + fn to_tokens( &self, tokens : &mut proc_macro2::TokenStream ) + { + self.0.to_tokens( tokens ); + } +} + +impl< T, Marker > core::ops::Deref for AttributePropertySyn< T, Marker > +where T : syn::parse::Parse + quote::ToTokens +{ + type Target = T; + #[ inline( always ) ] + fn deref( &self ) -> &T + { + &self.0 + } +} + +impl< T, Marker > AsRef< T > for AttributePropertySyn< T, Marker > +where T : syn::parse::Parse + quote::ToTokens +{ + #[ inline( always ) ] + fn as_ref( &self ) -> &T + { + &self.0 + } +} + +impl< T, Marker > From< T > for AttributePropertySyn< T, Marker > +where T : syn::parse::Parse + quote::ToTokens +{ + #[ inline( always ) ] + fn from( src : T ) -> Self + { + Self( src, Default::default() ) + } +} diff --git a/module/core/macro_tools/tests/inc/attr_prop_test.rs b/module/core/macro_tools/tests/inc/attr_prop_test.rs index 6274513ad2..67acaf75a8 100644 --- a/module/core/macro_tools/tests/inc/attr_prop_test.rs +++ b/module/core/macro_tools/tests/inc/attr_prop_test.rs @@ -100,3 +100,14 @@ fn attr_prop_test() assert_eq!( parsed.debug.internal(), false ); } + +#[ test ] +fn attribute_property_enabled() +{ + // Test default value + let attr : AttributePropertyEnabled = Default::default(); + assert_eq!( attr.internal(), None ); + assert_eq!( attr.value( true ), true ); + assert_eq!( attr.value( false ), false ); + +} From 56df95f1cfd6876cf3e8e463a1eb80c3ca1684af Mon Sep 17 00:00:00 2001 From: wandalen Date: Tue, 28 May 2024 17:35:36 +0300 Subject: [PATCH 09/59] macro_tools : evolve props --- .../inc/from_inner_variants_collisions.rs | 12 ------ ...from_inner_variants_duplicates_all_off.rs} | 4 ++ ...from_inner_variants_duplicates_some_off.rs | 41 ++++++++++++++++++ ...ariants_duplicates_some_off_default_off.rs | 42 +++++++++++++++++++ module/core/derive_tools/tests/inc/mod.rs | 8 +++- .../core/derive_tools_meta/src/derive/from.rs | 40 ++---------------- 6 files changed, 97 insertions(+), 50 deletions(-) rename module/core/derive_tools/tests/inc/{from_inner_variants_duplicates.rs => from_inner_variants_duplicates_all_off.rs} (93%) create mode 100644 module/core/derive_tools/tests/inc/from_inner_variants_duplicates_some_off.rs create mode 100644 module/core/derive_tools/tests/inc/from_inner_variants_duplicates_some_off_default_off.rs diff --git a/module/core/derive_tools/tests/inc/from_inner_variants_collisions.rs b/module/core/derive_tools/tests/inc/from_inner_variants_collisions.rs index e04334e1fc..d7bb05fa83 100644 --- a/module/core/derive_tools/tests/inc/from_inner_variants_collisions.rs +++ b/module/core/derive_tools/tests/inc/from_inner_variants_collisions.rs @@ -25,15 +25,3 @@ pub enum GetData // == end of generated include!( "./only_test/from_inner_variants.rs" ); - -// xxx2 : implement attribute `#[ from( off ) ]` -// -// #[ derive( Debug, PartialEq, From ) ] -// // #[ debug ] -// pub enum GetData< 'a, T > -// where -// T : ToString + ?Sized, -// { -// FromBin( &'static [ u8 ] ), -// FromT( &'a T ), -// } diff --git a/module/core/derive_tools/tests/inc/from_inner_variants_duplicates.rs b/module/core/derive_tools/tests/inc/from_inner_variants_duplicates_all_off.rs similarity index 93% rename from module/core/derive_tools/tests/inc/from_inner_variants_duplicates.rs rename to module/core/derive_tools/tests/inc/from_inner_variants_duplicates_all_off.rs index 4b0488aecb..87e5ebd2f3 100644 --- a/module/core/derive_tools/tests/inc/from_inner_variants_duplicates.rs +++ b/module/core/derive_tools/tests/inc/from_inner_variants_duplicates_all_off.rs @@ -8,9 +8,13 @@ pub enum GetData { Nothing, Nothing2, + #[ from( off ) ] FromString( String ), + #[ from( off ) ] FromString2( String ), + #[ from( off ) ] FromPair( String, String ), + #[ from( off ) ] FromPair2( String, String ), FromBin( &'static [ u8 ] ), Nothing3, diff --git a/module/core/derive_tools/tests/inc/from_inner_variants_duplicates_some_off.rs b/module/core/derive_tools/tests/inc/from_inner_variants_duplicates_some_off.rs new file mode 100644 index 0000000000..527d668a75 --- /dev/null +++ b/module/core/derive_tools/tests/inc/from_inner_variants_duplicates_some_off.rs @@ -0,0 +1,41 @@ +#![ allow( dead_code ) ] +#[ allow( unused_imports ) ] +use super::*; + +#[ derive( Debug, PartialEq, the_module::From ) ] +// #[ debug ] +pub enum GetData +{ + Nothing, + Nothing2, + #[ from( off ) ] + FromString( String ), + FromString2( String ), + #[ from( off ) ] + FromPair( String, String ), + FromPair2( String, String ), + FromBin( &'static [ u8 ] ), + Nothing3, +} + +// == begin of generated + +// == end of generated + +#[ test ] +fn variant_from() +{ + + let got : GetData = From::from( &b"abc"[ .. ] ); + let exp = GetData::FromBin( b"abc" ); + a_id!( got, exp ); + + let got : GetData = From::from( "abc".to_string() ); + let exp = GetData::FromString2( "abc".to_string() ); + a_id!( got, exp ); + + let got : GetData = From::from( ( "a".to_string(), "b".to_string() ) ); + let exp = GetData::FromPair2( "a".to_string(), "b".to_string() ); + a_id!( got, exp ); + +} diff --git a/module/core/derive_tools/tests/inc/from_inner_variants_duplicates_some_off_default_off.rs b/module/core/derive_tools/tests/inc/from_inner_variants_duplicates_some_off_default_off.rs new file mode 100644 index 0000000000..e699bc729a --- /dev/null +++ b/module/core/derive_tools/tests/inc/from_inner_variants_duplicates_some_off_default_off.rs @@ -0,0 +1,42 @@ +#![ allow( dead_code ) ] +#[ allow( unused_imports ) ] +use super::*; + +#[ derive( Debug, PartialEq, the_module::From ) ] +#[ from( off ) ] +// #[ debug ] +pub enum GetData +{ + Nothing, + Nothing2, + FromString( String ), + #[ from( on ) ] + FromString2( String ), + FromPair( String, String ), + #[ from( on ) ] + FromPair2( String, String ), + FromBin( &'static [ u8 ] ), + Nothing3, +} + +// == begin of generated + +// == end of generated + +#[ test ] +fn variant_from() +{ + + let got : GetData = From::from( &b"abc"[ .. ] ); + let exp = GetData::FromBin( b"abc" ); + a_id!( got, exp ); + + let got : GetData = From::from( "abc".to_string() ); + let exp = GetData::FromString2( "abc".to_string() ); + a_id!( got, exp ); + + let got : GetData = From::from( ( "a".to_string(), "b".to_string() ) ); + let exp = GetData::FromPair2( "a".to_string(), "b".to_string() ); + a_id!( got, exp ); + +} diff --git a/module/core/derive_tools/tests/inc/mod.rs b/module/core/derive_tools/tests/inc/mod.rs index 382e7b7ff2..3c20ac2bd1 100644 --- a/module/core/derive_tools/tests/inc/mod.rs +++ b/module/core/derive_tools/tests/inc/mod.rs @@ -68,8 +68,14 @@ mod from_inner_multiple_test; mod from_inner_variants_manual; #[ cfg( feature = "derive_from" ) ] mod from_inner_variants_derive; + +#[ cfg( feature = "derive_from" ) ] +mod from_inner_variants_duplicates_all_off; #[ cfg( feature = "derive_from" ) ] -mod from_inner_variants_duplicates; +mod from_inner_variants_duplicates_some_off; +#[ cfg( feature = "derive_from" ) ] +mod from_inner_variants_duplicates_some_off_default_off; + #[ cfg( feature = "derive_from" ) ] mod from_inner_variants_generics; #[ cfg( feature = "derive_from" ) ] diff --git a/module/core/derive_tools_meta/src/derive/from.rs b/module/core/derive_tools_meta/src/derive/from.rs index 966cef9a6b..d8a8cb1959 100644 --- a/module/core/derive_tools_meta/src/derive/from.rs +++ b/module/core/derive_tools_meta/src/derive/from.rs @@ -104,7 +104,9 @@ pub fn from( input : proc_macro::TokenStream ) -> Result< proc_macro2::TokenStre let variants_result : Result< Vec< proc_macro2::TokenStream > > = item.variants.iter().map( | variant | { - if map[ & variant.fields.to_token_stream().to_string() ] <= 1 + // don't do automatic off + // if map[ & variant.fields.to_token_stream().to_string() ] <= 1 + if true { variant_generate ( @@ -446,42 +448,6 @@ impl FieldAttributes /// `#[ from( off, hint : true ) ]` /// -// #[ derive( Default ) ] -// pub struct AttributeFrom -// { -// /// Specifies whether we should generate From implementation for the field. -// /// Can be altered using `on` and `off` attributes -// pub enabled : Option< bool >, -// /// Specifies whether to provide a sketch of generated From or not. -// /// Defaults to `false`, which means no hint is provided unless explicitly requested. -// pub hint : bool, -// } -// -// impl AttributeFrom -// { -// -// const KEYWORD : &'static str = "from"; -// -// pub fn from_meta( attr : &syn::Attribute ) -> Result< Self > -// { -// match attr.meta -// { -// syn::Meta::List( ref meta_list ) => -// { -// return syn::parse2::< AttributeFrom >( meta_list.tokens.clone() ); -// }, -// syn::Meta::Path( ref _path ) => -// { -// return Ok( Default::default() ) -// }, -// _ => return_syn_err!( attr, "Expects an attribute of format #[ from( off ) ] -// .\nGot: {}", qt!{ #attr } ), -// } -// } -// -// } -// xxx : clean - #[ derive( Debug, Default ) ] pub struct AttributeFrom { From 1e6a96bcd3d3a3f7cbe1a27426db10349d8278ad Mon Sep 17 00:00:00 2001 From: wandalen Date: Tue, 28 May 2024 18:11:51 +0300 Subject: [PATCH 10/59] derive_tools : from : item-level config --- .../from_inner_variants_duplicates_all_off.rs | 18 +- ...from_inner_variants_duplicates_some_off.rs | 18 +- ...ariants_duplicates_some_off_default_off.rs | 19 +- .../from_inner_variants_duplicates.rs | 20 ++ .../core/derive_tools_meta/src/derive/from.rs | 226 ++++++++++++++++-- module/core/former_meta/src/derive_former.rs | 2 +- .../src/derive_former/struct_attrs.rs | 12 +- module/core/macro_tools/Readme.md | 18 +- .../examples/macro_tools_attr_prop.rs | 18 +- 9 files changed, 255 insertions(+), 96 deletions(-) create mode 100644 module/core/derive_tools/tests/inc/only_test/from_inner_variants_duplicates.rs diff --git a/module/core/derive_tools/tests/inc/from_inner_variants_duplicates_all_off.rs b/module/core/derive_tools/tests/inc/from_inner_variants_duplicates_all_off.rs index 87e5ebd2f3..8d352850ff 100644 --- a/module/core/derive_tools/tests/inc/from_inner_variants_duplicates_all_off.rs +++ b/module/core/derive_tools/tests/inc/from_inner_variants_duplicates_all_off.rs @@ -42,20 +42,4 @@ impl From< ( String, String ) > for GetData // == end of generated -#[ test ] -fn variant_from() -{ - - let got : GetData = From::from( &b"abc"[ .. ] ); - let exp = GetData::FromBin( b"abc" ); - a_id!( got, exp ); - - let got : GetData = From::from( "abc".to_string() ); - let exp = GetData::FromString2( "abc".to_string() ); - a_id!( got, exp ); - - let got : GetData = From::from( ( "a".to_string(), "b".to_string() ) ); - let exp = GetData::FromPair2( "a".to_string(), "b".to_string() ); - a_id!( got, exp ); - -} +include!( "./only_test/from_inner_variants_duplicates.rs" ); diff --git a/module/core/derive_tools/tests/inc/from_inner_variants_duplicates_some_off.rs b/module/core/derive_tools/tests/inc/from_inner_variants_duplicates_some_off.rs index 527d668a75..1fa60cb598 100644 --- a/module/core/derive_tools/tests/inc/from_inner_variants_duplicates_some_off.rs +++ b/module/core/derive_tools/tests/inc/from_inner_variants_duplicates_some_off.rs @@ -22,20 +22,4 @@ pub enum GetData // == end of generated -#[ test ] -fn variant_from() -{ - - let got : GetData = From::from( &b"abc"[ .. ] ); - let exp = GetData::FromBin( b"abc" ); - a_id!( got, exp ); - - let got : GetData = From::from( "abc".to_string() ); - let exp = GetData::FromString2( "abc".to_string() ); - a_id!( got, exp ); - - let got : GetData = From::from( ( "a".to_string(), "b".to_string() ) ); - let exp = GetData::FromPair2( "a".to_string(), "b".to_string() ); - a_id!( got, exp ); - -} +include!( "./only_test/from_inner_variants_duplicates.rs" ); diff --git a/module/core/derive_tools/tests/inc/from_inner_variants_duplicates_some_off_default_off.rs b/module/core/derive_tools/tests/inc/from_inner_variants_duplicates_some_off_default_off.rs index e699bc729a..99de87ff1c 100644 --- a/module/core/derive_tools/tests/inc/from_inner_variants_duplicates_some_off_default_off.rs +++ b/module/core/derive_tools/tests/inc/from_inner_variants_duplicates_some_off_default_off.rs @@ -15,6 +15,7 @@ pub enum GetData FromPair( String, String ), #[ from( on ) ] FromPair2( String, String ), + #[ from( on ) ] FromBin( &'static [ u8 ] ), Nothing3, } @@ -23,20 +24,4 @@ pub enum GetData // == end of generated -#[ test ] -fn variant_from() -{ - - let got : GetData = From::from( &b"abc"[ .. ] ); - let exp = GetData::FromBin( b"abc" ); - a_id!( got, exp ); - - let got : GetData = From::from( "abc".to_string() ); - let exp = GetData::FromString2( "abc".to_string() ); - a_id!( got, exp ); - - let got : GetData = From::from( ( "a".to_string(), "b".to_string() ) ); - let exp = GetData::FromPair2( "a".to_string(), "b".to_string() ); - a_id!( got, exp ); - -} +include!( "./only_test/from_inner_variants_duplicates.rs" ); diff --git a/module/core/derive_tools/tests/inc/only_test/from_inner_variants_duplicates.rs b/module/core/derive_tools/tests/inc/only_test/from_inner_variants_duplicates.rs new file mode 100644 index 0000000000..9b126ff42e --- /dev/null +++ b/module/core/derive_tools/tests/inc/only_test/from_inner_variants_duplicates.rs @@ -0,0 +1,20 @@ +#[ allow( unused_imports ) ] +use super::*; + +#[ test ] +fn variant_from_duplicates() +{ + + let got : GetData = From::from( &b"abc"[ .. ] ); + let exp = GetData::FromBin( b"abc" ); + a_id!( got, exp ); + + let got : GetData = From::from( "abc".to_string() ); + let exp = GetData::FromString2( "abc".to_string() ); + a_id!( got, exp ); + + let got : GetData = From::from( ( "a".to_string(), "b".to_string() ) ); + let exp = GetData::FromPair2( "a".to_string(), "b".to_string() ); + a_id!( got, exp ); + +} diff --git a/module/core/derive_tools_meta/src/derive/from.rs b/module/core/derive_tools_meta/src/derive/from.rs index d8a8cb1959..6e59520981 100644 --- a/module/core/derive_tools_meta/src/derive/from.rs +++ b/module/core/derive_tools_meta/src/derive/from.rs @@ -10,7 +10,6 @@ use macro_tools:: AttributeComponent, AttributePropertyComponent, AttributePropertyBoolean, - // AttributePropertyEnabled, }; use former_types::ComponentAssign; @@ -26,6 +25,7 @@ pub fn from( input : proc_macro::TokenStream ) -> Result< proc_macro2::TokenStre let original_input = input.clone(); let parsed = syn::parse::< StructLike >( input )?; let has_debug = attr::has_debug( parsed.attrs().iter() )?; + let item_attrs = ItemAttributes::from_attrs( parsed.attrs().iter() )?; let item_name = &parsed.ident(); let ( _generics_with_defaults, generics_impl, generics_ty, generics_where ) @@ -111,6 +111,7 @@ pub fn from( input : proc_macro::TokenStream ) -> Result< proc_macro2::TokenStre variant_generate ( item_name, + &item_attrs, &generics_impl, &generics_ty, &generics_where, @@ -145,6 +146,7 @@ pub fn from( input : proc_macro::TokenStream ) -> Result< proc_macro2::TokenStre fn variant_generate ( item_name : &syn::Ident, + item_attrs : &ItemAttributes, generics_impl : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, generics_ty : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, generics_where: &syn::punctuated::Punctuated< syn::WherePredicate, syn::token::Comma >, @@ -156,7 +158,7 @@ fn variant_generate let fields = &variant.fields; let attrs = FieldAttributes::from_attrs( variant.attrs.iter() )?; - if !attrs.config.enabled.value( true ) + if !attrs.config.enabled.value( item_attrs.config.enabled.value( true ) ) { return Ok( qt!{} ) } @@ -381,6 +383,188 @@ fn generate_unit // xxx2 : get completed +// == item attributes + +/// +/// Attributes of the whole tiem +/// + +/// Represents the attributes of a struct. Aggregates all its attributes. +#[ derive( Debug, Default ) ] +pub struct ItemAttributes +{ + /// Attribute for customizing generated code. + pub config : ItemAttributeConfig, +} + +impl ItemAttributes +{ + + pub fn from_attrs< 'a >( attrs : impl Iterator< Item = &'a syn::Attribute > ) -> Result< Self > + { + let mut result = Self::default(); + + let error = | attr : &syn::Attribute | -> syn::Error + { + let known_attributes = const_format::concatcp! + ( + "Known attirbutes are : ", + "debug", + ", ", ItemAttributeConfig::KEYWORD, + ".", + ); + syn_err! + ( + attr, + "Expects an attribute of format '#[ attribute( key1 = val1, key2 = val2 ) ]'\n {known_attributes}\n But got: '{}'", + qt!{ #attr } + ) + }; + + for attr in attrs + { + + let key_ident = attr.path().get_ident().ok_or_else( || error( attr ) )?; + let key_str = format!( "{}", key_ident ); + + if attr::is_standard( &key_str ) + { + continue; + } + + match key_str.as_ref() + { + ItemAttributeConfig::KEYWORD => result.assign( ItemAttributeConfig::from_meta( attr )? ), + "debug" => {} + _ => (), + // _ => return Err( error( attr ) ), + // xxx + } + } + + Ok( result ) + } + +} + +/// +/// Attribute to hold parameters of forming for a specific field or variant. +/// For example to avoid code From generation for it. +/// +/// `#[ from( off, hint : true ) ]` +/// + +#[ derive( Debug, Default ) ] +pub struct ItemAttributeConfig +{ + /// Specifies whether `From` implementation for fields/variants should be generated by default. + /// Can be altered using `on` and `off` attributes. But default it's `on`. + /// `#[ from( on ) ]` - `From` is generated unless `off` for the field/variant is explicitly specified. + /// `#[ from( off ) ]` - `From` is not generated unless `on` for the field/variant is explicitly specified. + pub enabled : AttributePropertyEnabled, +} + +impl AttributeComponent for ItemAttributeConfig +{ + const KEYWORD : &'static str = "from"; + + fn from_meta( attr : &syn::Attribute ) -> Result< Self > + { + match attr.meta + { + syn::Meta::List( ref meta_list ) => + { + return syn::parse2::< ItemAttributeConfig >( meta_list.tokens.clone() ); + }, + syn::Meta::Path( ref _path ) => + { + return Ok( Default::default() ) + }, + _ => return_syn_err!( attr, "Expects an attribute of format `#[ from( on ) ]`. \nGot: {}", qt!{ #attr } ), + } + } + +} + +impl< IntoT > ComponentAssign< ItemAttributeConfig, IntoT > for ItemAttributes +where + IntoT : Into< ItemAttributeConfig >, +{ + #[ inline( always ) ] + fn assign( &mut self, component : IntoT ) + { + self.config = component.into(); + } +} + +impl< IntoT > ComponentAssign< AttributePropertyEnabled, IntoT > for ItemAttributeConfig +where + IntoT : Into< AttributePropertyEnabled >, +{ + #[ inline( always ) ] + fn assign( &mut self, component : IntoT ) + { + self.enabled = component.into(); + } +} + +impl syn::parse::Parse for ItemAttributeConfig +{ + fn parse( input : syn::parse::ParseStream< '_ > ) -> syn::Result< Self > + { + let mut result = Self::default(); + + let error = | ident : &syn::Ident | -> syn::Error + { + let known = const_format::concatcp! + ( + "Known entries of attribute ", ItemAttributeConfig::KEYWORD, " are : ", + AttributePropertyEnabled::KEYWORD_ON, + ", ", AttributePropertyEnabled::KEYWORD_OFF, + ".", + ); + syn_err! + ( + ident, + r#"Expects an attribute of format '#[ from( off ) ]' + {known} + But got: '{}' +"#, + qt!{ #ident } + ) + }; + + while !input.is_empty() + { + let lookahead = input.lookahead1(); + if lookahead.peek( syn::Ident ) + { + let ident : syn::Ident = input.parse()?; + match ident.to_string().as_str() + { + AttributePropertyEnabled::KEYWORD_ON => result.assign( AttributePropertyEnabled::from( true ) ), + AttributePropertyEnabled::KEYWORD_OFF => result.assign( AttributePropertyEnabled::from( false ) ), + _ => return Err( error( &ident ) ), + } + } + else + { + return Err( lookahead.error() ); + } + + // Optional comma handling + if input.peek( syn::Token![ , ] ) + { + input.parse::< syn::Token![ , ] >()?; + } + } + + Ok( result ) + } +} + +// == field attributes + /// /// Attributes of a field / variant /// @@ -389,8 +573,8 @@ fn generate_unit #[ derive( Debug, Default ) ] pub struct FieldAttributes { - /// Attribute for customizing the mutation process. - pub config : AttributeFrom, + /// Attribute for customizing generated code. + pub config : FieldAttributeConfig, } impl FieldAttributes @@ -406,7 +590,7 @@ impl FieldAttributes ( "Known attirbutes are : ", "debug", - ", ", AttributeFrom::KEYWORD, + ", ", FieldAttributeConfig::KEYWORD, ".", ); syn_err! @@ -430,7 +614,7 @@ impl FieldAttributes match key_str.as_ref() { - AttributeFrom::KEYWORD => result.assign( AttributeFrom::from_meta( attr )? ), + FieldAttributeConfig::KEYWORD => result.assign( FieldAttributeConfig::from_meta( attr )? ), "debug" => {} _ => return Err( error( attr ) ), } @@ -449,7 +633,7 @@ impl FieldAttributes /// #[ derive( Debug, Default ) ] -pub struct AttributeFrom +pub struct FieldAttributeConfig { /// Specifies whether we should generate From implementation for the field. /// Can be altered using `on` and `off` attributes @@ -457,9 +641,10 @@ pub struct AttributeFrom /// Specifies whether to provide a sketch of generated From or not. /// Defaults to `false`, which means no hint is provided unless explicitly requested. pub hint : AttributePropertyHint, + // qqq : xxx : implement } -impl AttributeComponent for AttributeFrom +impl AttributeComponent for FieldAttributeConfig { const KEYWORD : &'static str = "from"; @@ -469,7 +654,7 @@ impl AttributeComponent for AttributeFrom { syn::Meta::List( ref meta_list ) => { - return syn::parse2::< AttributeFrom >( meta_list.tokens.clone() ); + return syn::parse2::< FieldAttributeConfig >( meta_list.tokens.clone() ); }, syn::Meta::Path( ref _path ) => { @@ -481,9 +666,9 @@ impl AttributeComponent for AttributeFrom } -impl< IntoT > ComponentAssign< AttributeFrom, IntoT > for FieldAttributes +impl< IntoT > ComponentAssign< FieldAttributeConfig, IntoT > for FieldAttributes where - IntoT : Into< AttributeFrom >, + IntoT : Into< FieldAttributeConfig >, { #[ inline( always ) ] fn assign( &mut self, component : IntoT ) @@ -492,7 +677,7 @@ where } } -impl< IntoT > ComponentAssign< AttributePropertyEnabled, IntoT > for AttributeFrom +impl< IntoT > ComponentAssign< AttributePropertyEnabled, IntoT > for FieldAttributeConfig where IntoT : Into< AttributePropertyEnabled >, { @@ -503,7 +688,7 @@ where } } -impl< IntoT > ComponentAssign< AttributePropertyHint, IntoT > for AttributeFrom +impl< IntoT > ComponentAssign< AttributePropertyHint, IntoT > for FieldAttributeConfig where IntoT : Into< AttributePropertyHint >, { @@ -514,7 +699,7 @@ where } } -impl syn::parse::Parse for AttributeFrom +impl syn::parse::Parse for FieldAttributeConfig { fn parse( input : syn::parse::ParseStream< '_ > ) -> syn::Result< Self > { @@ -524,7 +709,7 @@ impl syn::parse::Parse for AttributeFrom { let known = const_format::concatcp! ( - "Known entries of attribute ", AttributeFrom::KEYWORD, " are : ", + "Known entries of attribute ", FieldAttributeConfig::KEYWORD, " are : ", AttributePropertyHint::KEYWORD, ", ", AttributePropertyEnabled::KEYWORD_ON, ", ", AttributePropertyEnabled::KEYWORD_OFF, @@ -533,7 +718,7 @@ impl syn::parse::Parse for AttributeFrom syn_err! ( ident, - r#"Expects an attribute of format '#[ from( custom = false, hint = false ) ]' + r#"Expects an attribute of format '#[ from( on, hint = false ) ]' {known} But got: '{}' "#, @@ -589,11 +774,12 @@ pub type AttributePropertyHint = AttributePropertyBoolean< AttributePropertyHint // = -/// Marker type for attribute property to indicates whether a custom code should be generated. -/// Defaults to `false`, meaning no custom code is generated unless explicitly requested. +/// Marker type for attribute property to indicates whether `From` implementation for fields/variants should be generated. #[ derive( Debug, Default, Clone, Copy ) ] pub struct AttributePropertyEnabledMarker; -/// Indicates whether a custom code should be generated. -/// Defaults to `false`, meaning no custom code is generated unless explicitly requested. +/// Specifies whether `From` implementation for fields/variants should be generated. +/// Can be altered using `on` and `off` attributes. But default it's `on`. pub type AttributePropertyEnabled = macro_tools::AttributePropertyEnabled< AttributePropertyEnabledMarker >; + +// == diff --git a/module/core/former_meta/src/derive_former.rs b/module/core/former_meta/src/derive_former.rs index d3093505cd..6b2290629b 100644 --- a/module/core/former_meta/src/derive_former.rs +++ b/module/core/former_meta/src/derive_former.rs @@ -150,7 +150,7 @@ pub fn former( input : proc_macro::TokenStream ) -> Result< TokenStream > Err( err ) => return Err( err ), }; let has_debug = attr::has_debug( ast.attrs.iter() )?; - let struct_attrs = StructAttributes::from_attrs( ast.attrs.iter() )?; + let struct_attrs = ItemAttributes::from_attrs( ast.attrs.iter() )?; /* names */ diff --git a/module/core/former_meta/src/derive_former/struct_attrs.rs b/module/core/former_meta/src/derive_former/struct_attrs.rs index be4f4f476e..9f3b64990b 100644 --- a/module/core/former_meta/src/derive_former/struct_attrs.rs +++ b/module/core/former_meta/src/derive_former/struct_attrs.rs @@ -18,7 +18,7 @@ use former_types::{ ComponentAssign }; /// Represents the attributes of a struct, including storage fields, mutator, and perform attributes. #[ derive( Debug, Default ) ] -pub struct StructAttributes +pub struct ItemAttributes { /// Optional attribute for storage-specific fields. /// This field is used to specify fields that should be part of the storage but not the final formed structure. @@ -33,7 +33,7 @@ pub struct StructAttributes pub perform : Option< AttributePerform >, } -impl StructAttributes +impl ItemAttributes { pub fn from_attrs< 'a >( attrs : impl Iterator< Item = &'a syn::Attribute > ) -> Result< Self > @@ -124,7 +124,7 @@ impl StructAttributes // } // } // -// Ok( StructAttributes { perform, storage_fields, mutator } ) +// Ok( ItemAttributes { perform, storage_fields, mutator } ) // } /// @@ -240,7 +240,7 @@ impl AttributeComponent for AttributeStorageFields } -impl< IntoT > ComponentAssign< AttributeStorageFields, IntoT > for StructAttributes +impl< IntoT > ComponentAssign< AttributeStorageFields, IntoT > for ItemAttributes where IntoT : Into< AttributeStorageFields >, { @@ -311,7 +311,7 @@ impl AttributeComponent for AttributeMutator } -impl< IntoT > ComponentAssign< AttributeMutator, IntoT > for StructAttributes +impl< IntoT > ComponentAssign< AttributeMutator, IntoT > for ItemAttributes where IntoT : Into< AttributeMutator >, { @@ -442,7 +442,7 @@ impl syn::parse::Parse for AttributePerform } } -impl< IntoT > ComponentAssign< AttributePerform, IntoT > for StructAttributes +impl< IntoT > ComponentAssign< AttributePerform, IntoT > for ItemAttributes where IntoT : Into< AttributePerform >, { diff --git a/module/core/macro_tools/Readme.md b/module/core/macro_tools/Readme.md index 7048a69611..3d805ccdd9 100644 --- a/module/core/macro_tools/Readme.md +++ b/module/core/macro_tools/Readme.md @@ -61,7 +61,7 @@ are parsed using reusable components from a library. The example shows how to us `AttributePropertyComponent` and `AttributeComponent`. The `ComponentAssign` trait is also used to simplify the logic of assigning fields. -Attributes are collected into a `StructAttributes` struct, and attribute properties are parsed +Attributes are collected into a `ItemAttributes` struct, and attribute properties are parsed using reusable components like `AttributePropertyBoolean`. - `AttributeComponent`: A trait that defines how an attribute should be parsed from a `syn::Attribute`. @@ -101,18 +101,18 @@ fn main() /// Represents the attributes of a struct. Aggregates all its attributes. #[ derive( Debug, Default ) ] - pub struct StructAttributes + pub struct ItemAttributes { /// Attribute for customizing the mutation process. pub mutator : AttributeMutator, } - impl StructAttributes + impl ItemAttributes { - /// Constructs a `StructAttributes` instance from an iterator of attributes. + /// Constructs a `ItemAttributes` instance from an iterator of attributes. /// /// This function parses the provided attributes and assigns them to the - /// appropriate fields in the `StructAttributes` struct. + /// appropriate fields in the `ItemAttributes` struct. pub fn from_attrs< 'a >( attrs : impl Iterator< Item = & 'a syn::Attribute > ) -> Result< Self > { let mut result = Self::default(); @@ -200,8 +200,8 @@ fn main() } } - // Implement `ComponentAssign` trait to allow assigning `AttributeMutator` to `StructAttributes`. - impl< IntoT > ComponentAssign< AttributeMutator, IntoT > for StructAttributes + // Implement `ComponentAssign` trait to allow assigning `AttributeMutator` to `ItemAttributes`. + impl< IntoT > ComponentAssign< AttributeMutator, IntoT > for ItemAttributes where IntoT : Into< AttributeMutator >, { @@ -326,9 +326,9 @@ fn main() // == Test code - // Parse an attribute and construct a `StructAttributes` instance. + // Parse an attribute and construct a `ItemAttributes` instance. let input : syn::Attribute = syn::parse_quote!( #[ mutator( custom = true, hint = false ) ] ); - let attrs : StructAttributes = StructAttributes::from_attrs( std::iter::once( & input ) ).unwrap(); + let attrs : ItemAttributes = ItemAttributes::from_attrs( std::iter::once( & input ) ).unwrap(); println!( "{:?}", attrs ); // Test `AttributePropertyBoolean` functionality. diff --git a/module/core/macro_tools/examples/macro_tools_attr_prop.rs b/module/core/macro_tools/examples/macro_tools_attr_prop.rs index 31faaaedf3..b8284bce50 100644 --- a/module/core/macro_tools/examples/macro_tools_attr_prop.rs +++ b/module/core/macro_tools/examples/macro_tools_attr_prop.rs @@ -8,7 +8,7 @@ //! `AttributePropertyComponent` and `AttributeComponent`. The `ComponentAssign` trait is //! also used to simplify the logic of assigning fields. //! -//! Attributes are collected into a `StructAttributes` struct, and attribute properties are parsed +//! Attributes are collected into a `ItemAttributes` struct, and attribute properties are parsed //! using reusable components like `AttributePropertyBoolean`. //! //! - `AttributeComponent`: A trait that defines how an attribute should be parsed from a `syn::Attribute`. @@ -47,18 +47,18 @@ fn main() /// Represents the attributes of a struct. Aggregates all its attributes. #[ derive( Debug, Default ) ] - pub struct StructAttributes + pub struct ItemAttributes { /// Attribute for customizing the mutation process. pub mutator : AttributeMutator, } - impl StructAttributes + impl ItemAttributes { - /// Constructs a `StructAttributes` instance from an iterator of attributes. + /// Constructs a `ItemAttributes` instance from an iterator of attributes. /// /// This function parses the provided attributes and assigns them to the - /// appropriate fields in the `StructAttributes` struct. + /// appropriate fields in the `ItemAttributes` struct. pub fn from_attrs< 'a >( attrs : impl Iterator< Item = & 'a syn::Attribute > ) -> Result< Self > { let mut result = Self::default(); @@ -146,8 +146,8 @@ fn main() } } - // Implement `ComponentAssign` trait to allow assigning `AttributeMutator` to `StructAttributes`. - impl< IntoT > ComponentAssign< AttributeMutator, IntoT > for StructAttributes + // Implement `ComponentAssign` trait to allow assigning `AttributeMutator` to `ItemAttributes`. + impl< IntoT > ComponentAssign< AttributeMutator, IntoT > for ItemAttributes where IntoT : Into< AttributeMutator >, { @@ -272,9 +272,9 @@ fn main() // == test code - // Parse an attribute and construct a `StructAttributes` instance. + // Parse an attribute and construct a `ItemAttributes` instance. let input : syn::Attribute = syn::parse_quote!( #[ mutator( custom = true, hint = false ) ] ); - let attrs : StructAttributes = StructAttributes::from_attrs( std::iter::once( & input ) ).unwrap(); + let attrs : ItemAttributes = ItemAttributes::from_attrs( std::iter::once( & input ) ).unwrap(); println!( "{:?}", attrs ); // Test `AttributePropertyBoolean` functionality. From 28011e36de1478debf447f808604d5de89d63c67 Mon Sep 17 00:00:00 2001 From: wandalen Date: Tue, 28 May 2024 18:25:32 +0300 Subject: [PATCH 11/59] derive_tools : from : item-level config --- module/core/derive_tools/tests/inc/mod.rs | 2 - module/core/derive_tools_meta/Cargo.toml | 2 +- .../core/derive_tools_meta/src/derive/from.rs | 32 ++++++++++++- .../src/derive/variadic_from.rs | 1 - module/core/former_meta/src/derive_former.rs | 2 +- .../former_meta/src/derive_former/field.rs | 8 ++-- .../src/derive_former/field_attrs.rs | 6 ++- .../src/derive_former/struct_attrs.rs | 48 ++----------------- 8 files changed, 43 insertions(+), 58 deletions(-) diff --git a/module/core/derive_tools/tests/inc/mod.rs b/module/core/derive_tools/tests/inc/mod.rs index 3c20ac2bd1..779ae76708 100644 --- a/module/core/derive_tools/tests/inc/mod.rs +++ b/module/core/derive_tools/tests/inc/mod.rs @@ -98,5 +98,3 @@ mod inner_from_multiple_named_test; mod inner_from_unit_test; #[ cfg( feature = "derive_inner_from" ) ] mod inner_from_multiple_test; - -// xxx diff --git a/module/core/derive_tools_meta/Cargo.toml b/module/core/derive_tools_meta/Cargo.toml index 5d942547f4..074cd08b82 100644 --- a/module/core/derive_tools_meta/Cargo.toml +++ b/module/core/derive_tools_meta/Cargo.toml @@ -66,7 +66,7 @@ iter_tools = { workspace = true, features = [ "full" ] } former_types = { workspace = true, features = [ "enabled", "types_component_assign" ] } const_format = { version = "0.2.32" } -# xxx : qqq : optimize features set +# qqq : optimize features set [dev-dependencies] test_tools = { workspace = true } diff --git a/module/core/derive_tools_meta/src/derive/from.rs b/module/core/derive_tools_meta/src/derive/from.rs index 6e59520981..e47af38176 100644 --- a/module/core/derive_tools_meta/src/derive/from.rs +++ b/module/core/derive_tools_meta/src/derive/from.rs @@ -190,6 +190,34 @@ fn variant_generate ) }; + if attr.hint.into() + { + let hint = format! + ( + r#" +#[ automatically_derived ] +impl< {generics_impl} > From< {args} > for {item_name}< {generics_ty} > +where + {generics_where} +{{ + #[ inline ] + fn from( src : {args} ) -> Self + {{ + Self::{variant_name}( {use_src} ) + }} +}} + "#, + // format!( "{}", qt!{ #entry_typ } ), + ); + let about = format! + ( +r#"derive : From +item : {item_name} +field : {variant_name}"#, + ); + diag::report_print( about, original_input, hint ); + } + Ok ( qt! @@ -436,9 +464,9 @@ impl ItemAttributes { ItemAttributeConfig::KEYWORD => result.assign( ItemAttributeConfig::from_meta( attr )? ), "debug" => {} - _ => (), + _ => {}, // _ => return Err( error( attr ) ), - // xxx + // attributes does not have to be known } } diff --git a/module/core/derive_tools_meta/src/derive/variadic_from.rs b/module/core/derive_tools_meta/src/derive/variadic_from.rs index 8d178969f8..9c917dc025 100644 --- a/module/core/derive_tools_meta/src/derive/variadic_from.rs +++ b/module/core/derive_tools_meta/src/derive/variadic_from.rs @@ -18,7 +18,6 @@ pub fn variadic_from( input : proc_macro::TokenStream ) -> Result< proc_macro2:: let len = parsed.fields.len(); let from_trait = format_ident!( "From{len}", ); let from_method = format_ident!( "from{len}" ); - // xxx : test for zero fields let ( diff --git a/module/core/former_meta/src/derive_former.rs b/module/core/former_meta/src/derive_former.rs index 6b2290629b..3cde2ae40f 100644 --- a/module/core/former_meta/src/derive_former.rs +++ b/module/core/former_meta/src/derive_former.rs @@ -97,7 +97,7 @@ where let about = format! ( r#"derive : Former -structure : {stru}"#, +item : {stru}"#, ); diag::report_print( about, original_input, hint ); }; diff --git a/module/core/former_meta/src/derive_former/field.rs b/module/core/former_meta/src/derive_former/field.rs index 015eba4a1c..0956e5cffa 100644 --- a/module/core/former_meta/src/derive_former/field.rs +++ b/module/core/former_meta/src/derive_former/field.rs @@ -481,7 +481,7 @@ where let about = format! ( r#"derive : Former -structure : {stru} +item : {stru} field : {field_ident}"#, ); diag::report_print( about, original_input, hint ); @@ -712,7 +712,7 @@ where let about = format! ( r#"derive : Former -structure : {stru} +item : {stru} field : {field_ident}"#, ); diag::report_print( about, original_input, hint ); @@ -1003,7 +1003,7 @@ where let about = format! ( r#"derive : Former -structure : {stru} +item : {stru} field : {field_ident}"#, ); diag::report_print( about, original_input, hint ); @@ -1309,7 +1309,7 @@ where let about = format! ( r#"derive : Former -structure : {stru} +item : {stru} field : {field_ident}"#, ); diag::report_print( about, original_input, hint ); diff --git a/module/core/former_meta/src/derive_former/field_attrs.rs b/module/core/former_meta/src/derive_former/field_attrs.rs index 5f2e86b719..93b1b1a267 100644 --- a/module/core/former_meta/src/derive_former/field_attrs.rs +++ b/module/core/former_meta/src/derive_former/field_attrs.rs @@ -101,8 +101,10 @@ impl FieldAttributes AttributeSubformScalarSetter::KEYWORD => result.assign( AttributeSubformScalarSetter::from_meta( attr )? ), AttributeSubformCollectionSetter::KEYWORD => result.assign( AttributeSubformCollectionSetter::from_meta( attr )? ), AttributeSubformEntrySetter::KEYWORD => result.assign( AttributeSubformEntrySetter::from_meta( attr )? ), - "debug" => {} - _ => return Err( error( attr ) ), + "debug" => {}, + _ => {}, + // _ => return Err( error( attr ) ), + // attributes does not have to be known } } diff --git a/module/core/former_meta/src/derive_former/struct_attrs.rs b/module/core/former_meta/src/derive_former/struct_attrs.rs index 9f3b64990b..014e304f8a 100644 --- a/module/core/former_meta/src/derive_former/struct_attrs.rs +++ b/module/core/former_meta/src/derive_former/struct_attrs.rs @@ -76,57 +76,15 @@ impl ItemAttributes AttributeMutator::KEYWORD => result.assign( AttributeMutator::from_meta( attr )? ), AttributePerform::KEYWORD => result.assign( AttributePerform::from_meta( attr )? ), "debug" => {} - _ => return Err( error( attr ) ), + _ => {}, + // _ => return Err( error( attr ) ), + // attributes does not have to be known } } Ok( result ) } -// pub fn from_attrs< 'a >( attrs : impl Iterator< Item = &'a syn::Attribute > ) -> Result< Self > -// { -// let mut storage_fields = None; -// let mut mutator : AttributeMutator = Default::default(); -// let mut perform = None; -// -// for attr in attrs -// { -// let key_ident = attr.path().get_ident() -// .ok_or_else( || syn_err!( attr, "Expects an attribute of format #[ attribute( key1 = val1, key2 = val2 ) ], but got:\n {}", qt!{ #attr } ) )?; -// let key_str = format!( "{}", key_ident ); -// -// if attr::is_standard( &key_str ) -// { -// continue; -// } -// -// match key_str.as_ref() -// { -// AttributeStorageFields::KEYWORD => -// { -// storage_fields.replace( AttributeStorageFields::from_meta( attr )? ); -// } -// AttributeMutator::KEYWORD => -// { -// mutator = AttributeMutator::from_meta( attr )?; -// } -// AttributePerform::KEYWORD => -// { -// perform.replace( AttributePerform::from_meta( attr )? ); -// } -// "debug" => -// { -// } -// _ => -// { -// return Err( syn_err!( attr, "Known structure attirbutes are : `storage_fields`, `mutator`, `perform`, `debug`.\nUnknown structure attribute : {}", qt!{ #attr } ) ); -// } -// } -// } -// -// Ok( ItemAttributes { perform, storage_fields, mutator } ) -// } - /// /// Generate parts, used for generating `perform()`` method. /// From c0d0133c5eb6a8136d88338266be7748edd42dcc Mon Sep 17 00:00:00 2001 From: wandalen Date: Tue, 28 May 2024 18:30:56 +0300 Subject: [PATCH 12/59] derive_tools : from : hint working --- ...inner_variants_duplicates_some_off_default_off.rs | 2 ++ module/core/derive_tools_meta/src/derive/from.rs | 12 ++++++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/module/core/derive_tools/tests/inc/from_inner_variants_duplicates_some_off_default_off.rs b/module/core/derive_tools/tests/inc/from_inner_variants_duplicates_some_off_default_off.rs index 99de87ff1c..6bbbcb630d 100644 --- a/module/core/derive_tools/tests/inc/from_inner_variants_duplicates_some_off_default_off.rs +++ b/module/core/derive_tools/tests/inc/from_inner_variants_duplicates_some_off_default_off.rs @@ -11,6 +11,8 @@ pub enum GetData Nothing2, FromString( String ), #[ from( on ) ] + // #[ from( on, hint = true ) ] + // xxx : rename `hint` to `debug` and rid rid `off = true` FromString2( String ), FromPair( String, String ), #[ from( on ) ] diff --git a/module/core/derive_tools_meta/src/derive/from.rs b/module/core/derive_tools_meta/src/derive/from.rs index e47af38176..59d87c7e77 100644 --- a/module/core/derive_tools_meta/src/derive/from.rs +++ b/module/core/derive_tools_meta/src/derive/from.rs @@ -116,6 +116,7 @@ pub fn from( input : proc_macro::TokenStream ) -> Result< proc_macro2::TokenStre &generics_ty, &generics_where, variant, + &original_input, ) } else @@ -151,6 +152,7 @@ fn variant_generate generics_ty : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, generics_where: &syn::punctuated::Punctuated< syn::WherePredicate, syn::token::Comma >, variant : &syn::Variant, + original_input : &proc_macro::TokenStream, ) -> Result< proc_macro2::TokenStream > { @@ -190,15 +192,15 @@ fn variant_generate ) }; - if attr.hint.into() + if attrs.config.hint.into() { let hint = format! ( r#" #[ automatically_derived ] -impl< {generics_impl} > From< {args} > for {item_name}< {generics_ty} > +impl< {0} > From< {args} > for {item_name}< {1} > where - {generics_where} + {2} {{ #[ inline ] fn from( src : {args} ) -> Self @@ -207,7 +209,9 @@ where }} }} "#, - // format!( "{}", qt!{ #entry_typ } ), + format!( "{}", qt!{ #generics_impl } ), + format!( "{}", qt!{ #generics_ty } ), + format!( "{}", qt!{ #generics_where } ), ); let about = format! ( From 11f32431c70b87662b06f9c80dfaf21658e828c8 Mon Sep 17 00:00:00 2001 From: wandalen Date: Tue, 28 May 2024 23:36:27 +0300 Subject: [PATCH 13/59] macro_tools : property singletone --- module/core/macro_tools/src/attr_prop.rs | 1 + .../core/macro_tools/src/attr_prop/boolean.rs | 2 + .../core/macro_tools/src/attr_prop/enabled.rs | 30 +++--- .../src/attr_prop/optional_boolean.rs | 2 + .../macro_tools/src/attr_prop/optional_syn.rs | 2 + .../macro_tools/src/attr_prop/singletone.rs | 94 +++++++++++++++++++ module/core/macro_tools/src/attr_prop/syn.rs | 6 +- 7 files changed, 120 insertions(+), 17 deletions(-) create mode 100644 module/core/macro_tools/src/attr_prop/singletone.rs diff --git a/module/core/macro_tools/src/attr_prop.rs b/module/core/macro_tools/src/attr_prop.rs index 8b3b3e0f51..149683cb60 100644 --- a/module/core/macro_tools/src/attr_prop.rs +++ b/module/core/macro_tools/src/attr_prop.rs @@ -100,6 +100,7 @@ mod boolean; mod optional_boolean; mod syn; mod optional_syn; +mod singletone; /// Internal namespace. pub( crate ) mod private diff --git a/module/core/macro_tools/src/attr_prop/boolean.rs b/module/core/macro_tools/src/attr_prop/boolean.rs index dfa1c80fde..9a884b548e 100644 --- a/module/core/macro_tools/src/attr_prop/boolean.rs +++ b/module/core/macro_tools/src/attr_prop/boolean.rs @@ -108,12 +108,14 @@ pub struct AttributePropertyBoolean< Marker >( bool, ::core::marker::PhantomData impl< Marker > AttributePropertyBoolean< Marker > { /// Just unwraps and returns the internal data. + #[ inline( always ) ] pub fn internal( self ) -> bool { self.0 } /// Returns a reference to the internal boolean value. + #[ inline( always ) ] pub fn ref_internal( &self ) -> &bool { &self.0 diff --git a/module/core/macro_tools/src/attr_prop/enabled.rs b/module/core/macro_tools/src/attr_prop/enabled.rs index 96312093f4..ada5453e7f 100644 --- a/module/core/macro_tools/src/attr_prop/enabled.rs +++ b/module/core/macro_tools/src/attr_prop/enabled.rs @@ -1,8 +1,8 @@ //! A generic boolean attribute property. //! Defaults to `None`. //! -//! This property can have three states: `None`, `Some(true)`, or `Some(false)`. -//! It parses `on` and `off` keywords to represent `Some(true)` and `Some(false)` respectively. +//! This property can have three states: `None`, `Some( true )`, or `Some( false )`. +//! It parses `on` and `off` keywords to represent `Some( true )` and `Some( false )` respectively. //! //! # Example //! @@ -35,12 +35,13 @@ pub struct AttributePropertyEnabled< Marker = AttributePropertyEnabledMarker > impl< Marker > AttributePropertyEnabled< Marker > { + /// Keywords for parsing this attribute property. - pub const KEYWORDS : [& 'static str ; 2] = [ "on", "off" ]; + pub const KEYWORDS : [ &'static str ; 2 ] = [ "on", "off" ]; /// Keywords for parsing this attribute property. - pub const KEYWORD_OFF : & 'static str = "off"; + pub const KEYWORD_OFF : &'static str = "off"; /// Keywords for parsing this attribute property. - pub const KEYWORD_ON : & 'static str = "on"; + pub const KEYWORD_ON : &'static str = "on"; /// Return bool value: on/off, use argument as default if it's `None`. #[ inline ] @@ -53,28 +54,27 @@ impl< Marker > AttributePropertyEnabled< Marker > self.0.unwrap() } -} - -impl< Marker > AttributePropertyEnabled< Marker > -{ /// Unwraps and returns the internal optional boolean value. + #[ inline( always ) ] pub fn internal( self ) -> Option< bool > { self.0 } /// Returns a reference to the internal optional boolean value. - pub fn ref_internal( & self ) -> Option< & bool > + #[ inline( always ) ] + pub fn ref_internal( &self ) -> Option< &bool > { self.0.as_ref() } + } impl< Marker > AttributePropertyComponent for AttributePropertyEnabled< Marker > where Marker : AttributePropertyComponent, { - const KEYWORD : & 'static str = Marker::KEYWORD; + const KEYWORD : &'static str = Marker::KEYWORD; } impl< Marker > From< bool > for AttributePropertyEnabled< Marker > @@ -109,17 +109,17 @@ impl< Marker > core::ops::Deref for AttributePropertyEnabled< Marker > type Target = Option< bool >; #[ inline( always ) ] - fn deref( & self ) -> & Option< bool > + fn deref( &self ) -> &Option< bool > { - & self.0 + &self.0 } } impl< Marker > AsRef< Option< bool > > for AttributePropertyEnabled< Marker > { #[ inline( always ) ] - fn as_ref( & self ) -> & Option< bool > + fn as_ref( &self ) -> &Option< bool > { - & self.0 + &self.0 } } diff --git a/module/core/macro_tools/src/attr_prop/optional_boolean.rs b/module/core/macro_tools/src/attr_prop/optional_boolean.rs index f1111360b1..d48ebdaf84 100644 --- a/module/core/macro_tools/src/attr_prop/optional_boolean.rs +++ b/module/core/macro_tools/src/attr_prop/optional_boolean.rs @@ -13,12 +13,14 @@ pub struct AttributePropertyOptionalBoolean< Marker >( Option< bool >, ::core::m impl< Marker > AttributePropertyOptionalBoolean< Marker > { /// Just unwraps and returns the internal data. + #[ inline( always ) ] pub fn internal( self ) -> Option< bool > { self.0 } /// Returns a reference to the internal optional boolean value. + #[ inline( always ) ] pub fn ref_internal( &self ) -> Option< &bool > { self.0.as_ref() diff --git a/module/core/macro_tools/src/attr_prop/optional_syn.rs b/module/core/macro_tools/src/attr_prop/optional_syn.rs index 2dc4d8e0c9..9233b49709 100644 --- a/module/core/macro_tools/src/attr_prop/optional_syn.rs +++ b/module/core/macro_tools/src/attr_prop/optional_syn.rs @@ -18,12 +18,14 @@ where T : syn::parse::Parse + quote::ToTokens, { /// Just unwraps and returns the internal data. + #[ inline( always ) ] pub fn internal( self ) -> Option< T > { self.0 } /// Returns an Option reference to the internal data. + #[ inline( always ) ] pub fn ref_internal( &self ) -> Option< &T > { self.0.as_ref() diff --git a/module/core/macro_tools/src/attr_prop/singletone.rs b/module/core/macro_tools/src/attr_prop/singletone.rs new file mode 100644 index 0000000000..b932ff495d --- /dev/null +++ b/module/core/macro_tools/src/attr_prop/singletone.rs @@ -0,0 +1,94 @@ +//! A generic boolean attribute property. +//! Defaults to `None`. +//! +//! This property can have two states: `true`, or `false`. +//! +//! # Example +//! +//! ```ignore +//! #[ attribute( some ) ] +//! ``` +//! +//! This is useful for attributes that need to enable or disable features or flags. + +use crate::*; + +/// Default marker for `AttributePropertySingletone`. +#[ derive( Debug, Default, Clone, Copy ) ] +pub struct AttributePropertySingletoneMarker; + +/// A generic attribute property for switching on/off. +/// This property can have two states: `true`, or `false`. +/// Defaults to `false`. +/// +/// Unlike other properties, it does not implement parse, because it consists only of keyword which should be parsed outside of the property. +#[ derive( Debug, Default, Clone, Copy ) ] +pub struct AttributePropertySingletone< Marker = AttributePropertySingletoneMarker > +( + bool, + ::core::marker::PhantomData< Marker > +); + +impl< Marker > AttributePropertySingletone< Marker > +{ + + /// Unwraps and returns the internal optional boolean value. + #[ inline( always ) ] + pub fn internal( self ) -> bool + { + self.0 + } + + /// Returns a reference to the internal optional boolean value. + #[ inline( always ) ] + pub fn ref_internal( &self ) -> &bool + { + &self.0 + } + +} + +impl< Marker > AttributePropertyComponent for AttributePropertySingletone< Marker > +where + Marker : AttributePropertyComponent, +{ + const KEYWORD : &'static str = Marker::KEYWORD; +} + +impl< Marker > From< bool > for AttributePropertySingletone< Marker > +{ + #[ inline( always ) ] + fn from( src : bool ) -> Self + { + Self( src, Default::default() ) + } +} + +impl< Marker > From< AttributePropertySingletone< Marker > > for bool +{ + #[ inline( always ) ] + fn from( src : AttributePropertySingletone< Marker > ) -> Self + { + src.0 + } +} + +impl< Marker > core::ops::Deref for AttributePropertySingletone< Marker > +{ + type Target = bool; + + #[ inline( always ) ] + fn deref( &self ) -> &bool + { + &self.0 + } +} + +impl< Marker > AsRef< bool > for AttributePropertySingletone< Marker > +{ + #[ inline( always ) ] + fn as_ref( &self ) -> &bool + { + &self.0 + } +} diff --git a/module/core/macro_tools/src/attr_prop/syn.rs b/module/core/macro_tools/src/attr_prop/syn.rs index abd21fea38..93d9eaad5c 100644 --- a/module/core/macro_tools/src/attr_prop/syn.rs +++ b/module/core/macro_tools/src/attr_prop/syn.rs @@ -18,14 +18,16 @@ where T : syn::parse::Parse + quote::ToTokens, { /// Just unwraps and returns the internal data. - #[ allow( dead_code ) ] + // #[ allow( dead_code ) ] + #[ inline( always ) ] pub fn internal( self ) -> T { self.0 } /// Returns a reference to the internal data. - #[ allow( dead_code ) ] + // #[ allow( dead_code ) ] + #[ inline( always ) ] pub fn ref_internal( &self ) -> &T { &self.0 From cf6247cee5117e11c8950eb7fb62a69249a73657 Mon Sep 17 00:00:00 2001 From: wandalen Date: Tue, 28 May 2024 23:59:28 +0300 Subject: [PATCH 14/59] macro_tools : property singletone --- .../core/derive_tools_meta/src/derive/from.rs | 24 ++++++++++++------- module/core/macro_tools/src/attr_prop.rs | 19 ++++++++------- ...ptional_boolean.rs => boolean_optional.rs} | 0 .../macro_tools/src/attr_prop/singletone.rs | 7 +++--- .../{enabled.rs => singletone_optional.rs} | 17 ++++++------- .../{optional_syn.rs => syn_optional.rs} | 0 6 files changed, 40 insertions(+), 27 deletions(-) rename module/core/macro_tools/src/attr_prop/{optional_boolean.rs => boolean_optional.rs} (100%) rename module/core/macro_tools/src/attr_prop/{enabled.rs => singletone_optional.rs} (84%) rename module/core/macro_tools/src/attr_prop/{optional_syn.rs => syn_optional.rs} (100%) diff --git a/module/core/derive_tools_meta/src/derive/from.rs b/module/core/derive_tools_meta/src/derive/from.rs index 59d87c7e77..bda4cadca1 100644 --- a/module/core/derive_tools_meta/src/derive/from.rs +++ b/module/core/derive_tools_meta/src/derive/from.rs @@ -551,8 +551,8 @@ impl syn::parse::Parse for ItemAttributeConfig let known = const_format::concatcp! ( "Known entries of attribute ", ItemAttributeConfig::KEYWORD, " are : ", - AttributePropertyEnabled::KEYWORD_ON, - ", ", AttributePropertyEnabled::KEYWORD_OFF, + AttributePropertyEnabledMarker::KEYWORD_ON, + ", ", AttributePropertyEnabledMarker::KEYWORD_OFF, ".", ); syn_err! @@ -574,8 +574,8 @@ impl syn::parse::Parse for ItemAttributeConfig let ident : syn::Ident = input.parse()?; match ident.to_string().as_str() { - AttributePropertyEnabled::KEYWORD_ON => result.assign( AttributePropertyEnabled::from( true ) ), - AttributePropertyEnabled::KEYWORD_OFF => result.assign( AttributePropertyEnabled::from( false ) ), + AttributePropertyEnabledMarker::KEYWORD_ON => result.assign( AttributePropertyEnabled::from( true ) ), + AttributePropertyEnabledMarker::KEYWORD_OFF => result.assign( AttributePropertyEnabled::from( false ) ), _ => return Err( error( &ident ) ), } } @@ -743,8 +743,8 @@ impl syn::parse::Parse for FieldAttributeConfig ( "Known entries of attribute ", FieldAttributeConfig::KEYWORD, " are : ", AttributePropertyHint::KEYWORD, - ", ", AttributePropertyEnabled::KEYWORD_ON, - ", ", AttributePropertyEnabled::KEYWORD_OFF, + ", ", AttributePropertyEnabledMarker::KEYWORD_ON, + ", ", AttributePropertyEnabledMarker::KEYWORD_OFF, ".", ); syn_err! @@ -766,8 +766,8 @@ impl syn::parse::Parse for FieldAttributeConfig let ident : syn::Ident = input.parse()?; match ident.to_string().as_str() { - AttributePropertyEnabled::KEYWORD_ON => result.assign( AttributePropertyEnabled::from( true ) ), - AttributePropertyEnabled::KEYWORD_OFF => result.assign( AttributePropertyEnabled::from( false ) ), + AttributePropertyEnabledMarker::KEYWORD_ON => result.assign( AttributePropertyEnabled::from( true ) ), + AttributePropertyEnabledMarker::KEYWORD_OFF => result.assign( AttributePropertyEnabled::from( false ) ), AttributePropertyHint::KEYWORD => result.assign( AttributePropertyHint::parse( input )? ), _ => return Err( error( &ident ) ), } @@ -810,6 +810,14 @@ pub type AttributePropertyHint = AttributePropertyBoolean< AttributePropertyHint #[ derive( Debug, Default, Clone, Copy ) ] pub struct AttributePropertyEnabledMarker; +impl AttributePropertyEnabledMarker +{ + /// Keywords for parsing this attribute property. + pub const KEYWORD_OFF : &'static str = "off"; + /// Keywords for parsing this attribute property. + pub const KEYWORD_ON : &'static str = "on"; +} + /// Specifies whether `From` implementation for fields/variants should be generated. /// Can be altered using `on` and `off` attributes. But default it's `on`. pub type AttributePropertyEnabled = macro_tools::AttributePropertyEnabled< AttributePropertyEnabledMarker >; diff --git a/module/core/macro_tools/src/attr_prop.rs b/module/core/macro_tools/src/attr_prop.rs index 149683cb60..37fb31ca60 100644 --- a/module/core/macro_tools/src/attr_prop.rs +++ b/module/core/macro_tools/src/attr_prop.rs @@ -95,12 +95,12 @@ //! The `parse_quote!` macro is used to create a `syn::Attribute` instance with the attribute syntax, //! which is then parsed into the `MyAttributes` struct. The resulting `MyAttributes` instance is printed to the console. -mod enabled; +mod singletone; +mod singletone_optional; mod boolean; -mod optional_boolean; +mod boolean_optional; mod syn; -mod optional_syn; -mod singletone; +mod syn_optional; /// Internal namespace. pub( crate ) mod private @@ -145,12 +145,15 @@ pub mod exposed #[ allow( unused_imports ) ] pub use super:: { - enabled::AttributePropertyEnabled, - enabled::AttributePropertyEnabledMarker, + singletone::AttributePropertySingletone, + singletone::AttributePropertySingletoneMarker, + singletone_optional::AttributePropertyEnabled, + singletone_optional::AttributePropertyEnabledMarker, + boolean::AttributePropertyBoolean, - optional_boolean::AttributePropertyOptionalBoolean, + boolean_optional::AttributePropertyOptionalBoolean, syn::AttributePropertySyn, - optional_syn::AttributePropertyOptionalSyn, + syn_optional::AttributePropertyOptionalSyn, }; } diff --git a/module/core/macro_tools/src/attr_prop/optional_boolean.rs b/module/core/macro_tools/src/attr_prop/boolean_optional.rs similarity index 100% rename from module/core/macro_tools/src/attr_prop/optional_boolean.rs rename to module/core/macro_tools/src/attr_prop/boolean_optional.rs diff --git a/module/core/macro_tools/src/attr_prop/singletone.rs b/module/core/macro_tools/src/attr_prop/singletone.rs index b932ff495d..9cbfbc8c3b 100644 --- a/module/core/macro_tools/src/attr_prop/singletone.rs +++ b/module/core/macro_tools/src/attr_prop/singletone.rs @@ -1,4 +1,4 @@ -//! A generic boolean attribute property. +//! A generic `bool` attribute property which consists of only keyword. //! Defaults to `None`. //! //! This property can have two states: `true`, or `false`. @@ -14,10 +14,11 @@ use crate::*; /// Default marker for `AttributePropertySingletone`. +/// Used if no marker is defined as parameter. #[ derive( Debug, Default, Clone, Copy ) ] pub struct AttributePropertySingletoneMarker; -/// A generic attribute property for switching on/off. +/// A generic boolean attribute property which consists of only keyword. /// This property can have two states: `true`, or `false`. /// Defaults to `false`. /// @@ -26,7 +27,7 @@ pub struct AttributePropertySingletoneMarker; pub struct AttributePropertySingletone< Marker = AttributePropertySingletoneMarker > ( bool, - ::core::marker::PhantomData< Marker > + ::core::marker::PhantomData< Marker >, ); impl< Marker > AttributePropertySingletone< Marker > diff --git a/module/core/macro_tools/src/attr_prop/enabled.rs b/module/core/macro_tools/src/attr_prop/singletone_optional.rs similarity index 84% rename from module/core/macro_tools/src/attr_prop/enabled.rs rename to module/core/macro_tools/src/attr_prop/singletone_optional.rs index ada5453e7f..ad388db1c6 100644 --- a/module/core/macro_tools/src/attr_prop/enabled.rs +++ b/module/core/macro_tools/src/attr_prop/singletone_optional.rs @@ -1,4 +1,4 @@ -//! A generic boolean attribute property. +//! A generic `Option< bool >` attribute property which consists of only keyword. //! Defaults to `None`. //! //! This property can have three states: `None`, `Some( true )`, or `Some( false )`. @@ -16,6 +16,7 @@ use crate::*; /// Default marker for `AttributePropertyEnabled`. +/// Used if no marker is defined as parameter. #[ derive( Debug, Default, Clone, Copy ) ] pub struct AttributePropertyEnabledMarker; @@ -30,18 +31,18 @@ pub struct AttributePropertyEnabledMarker; pub struct AttributePropertyEnabled< Marker = AttributePropertyEnabledMarker > ( Option< bool >, - ::core::marker::PhantomData< Marker > + ::core::marker::PhantomData< Marker >, ); impl< Marker > AttributePropertyEnabled< Marker > { - /// Keywords for parsing this attribute property. - pub const KEYWORDS : [ &'static str ; 2 ] = [ "on", "off" ]; - /// Keywords for parsing this attribute property. - pub const KEYWORD_OFF : &'static str = "off"; - /// Keywords for parsing this attribute property. - pub const KEYWORD_ON : &'static str = "on"; + // /// Keywords for parsing this attribute property. + // pub const KEYWORDS : [ &'static str ; 2 ] = [ "on", "off" ]; + // /// Keywords for parsing this attribute property. + // pub const KEYWORD_OFF : &'static str = "off"; + // /// Keywords for parsing this attribute property. + // pub const KEYWORD_ON : &'static str = "on"; /// Return bool value: on/off, use argument as default if it's `None`. #[ inline ] diff --git a/module/core/macro_tools/src/attr_prop/optional_syn.rs b/module/core/macro_tools/src/attr_prop/syn_optional.rs similarity index 100% rename from module/core/macro_tools/src/attr_prop/optional_syn.rs rename to module/core/macro_tools/src/attr_prop/syn_optional.rs From 274d2ff87f9c06eb7472dd3ebb4cd02704cbf3a9 Mon Sep 17 00:00:00 2001 From: wandalen Date: Wed, 29 May 2024 00:13:51 +0300 Subject: [PATCH 15/59] derive_tools : property hint - --- debug | 0 ...ariants_duplicates_some_off_default_off.rs | 4 +- .../core/derive_tools_meta/src/derive/from.rs | 44 +++++++++--------- .../src/derive_former/field_attrs.rs | 46 +++++++++---------- .../src/derive_former/struct_attrs.rs | 16 +++---- module/core/macro_tools/Readme.md | 24 +++++----- .../examples/macro_tools_attr_prop.rs | 30 ++++++------ 7 files changed, 82 insertions(+), 82 deletions(-) create mode 100644 debug diff --git a/debug b/debug new file mode 100644 index 0000000000..e69de29bb2 diff --git a/module/core/derive_tools/tests/inc/from_inner_variants_duplicates_some_off_default_off.rs b/module/core/derive_tools/tests/inc/from_inner_variants_duplicates_some_off_default_off.rs index 6bbbcb630d..8148a66320 100644 --- a/module/core/derive_tools/tests/inc/from_inner_variants_duplicates_some_off_default_off.rs +++ b/module/core/derive_tools/tests/inc/from_inner_variants_duplicates_some_off_default_off.rs @@ -10,8 +10,8 @@ pub enum GetData Nothing, Nothing2, FromString( String ), - #[ from( on ) ] - // #[ from( on, hint = true ) ] + // #[ from( on ) ] + #[ from( on, debug) ] // xxx : rename `hint` to `debug` and rid rid `off = true` FromString2( String ), FromPair( String, String ), diff --git a/module/core/derive_tools_meta/src/derive/from.rs b/module/core/derive_tools_meta/src/derive/from.rs index bda4cadca1..6ad6079288 100644 --- a/module/core/derive_tools_meta/src/derive/from.rs +++ b/module/core/derive_tools_meta/src/derive/from.rs @@ -9,7 +9,7 @@ use macro_tools:: Result, AttributeComponent, AttributePropertyComponent, - AttributePropertyBoolean, + AttributePropertySingletone, }; use former_types::ComponentAssign; @@ -192,9 +192,9 @@ fn variant_generate ) }; - if attrs.config.hint.into() + if attrs.config.debug.into() { - let hint = format! + let debug = format! ( r#" #[ automatically_derived ] @@ -219,7 +219,7 @@ r#"derive : From item : {item_name} field : {variant_name}"#, ); - diag::report_print( about, original_input, hint ); + diag::report_print( about, original_input, debug ); } Ok @@ -483,7 +483,7 @@ impl ItemAttributes /// Attribute to hold parameters of forming for a specific field or variant. /// For example to avoid code From generation for it. /// -/// `#[ from( off, hint : true ) ]` +/// `#[ from( on, debug ) ]` /// #[ derive( Debug, Default ) ] @@ -661,7 +661,7 @@ impl FieldAttributes /// Attribute to hold parameters of forming for a specific field or variant. /// For example to avoid code From generation for it. /// -/// `#[ from( off, hint : true ) ]` +/// `#[ from( on, debug ) ]` /// #[ derive( Debug, Default ) ] @@ -670,9 +670,9 @@ pub struct FieldAttributeConfig /// Specifies whether we should generate From implementation for the field. /// Can be altered using `on` and `off` attributes pub enabled : AttributePropertyEnabled, - /// Specifies whether to provide a sketch of generated From or not. - /// Defaults to `false`, which means no hint is provided unless explicitly requested. - pub hint : AttributePropertyHint, + /// Specifies whether to print a sketch of generated `From` or not. + /// Defaults to `false`, which means no code is printed unless explicitly requested. + pub debug : AttributePropertyDebug, // qqq : xxx : implement } @@ -720,14 +720,14 @@ where } } -impl< IntoT > ComponentAssign< AttributePropertyHint, IntoT > for FieldAttributeConfig +impl< IntoT > ComponentAssign< AttributePropertyDebug, IntoT > for FieldAttributeConfig where - IntoT : Into< AttributePropertyHint >, + IntoT : Into< AttributePropertyDebug >, { #[ inline( always ) ] fn assign( &mut self, component : IntoT ) { - self.hint = component.into(); + self.debug = component.into(); } } @@ -742,7 +742,7 @@ impl syn::parse::Parse for FieldAttributeConfig let known = const_format::concatcp! ( "Known entries of attribute ", FieldAttributeConfig::KEYWORD, " are : ", - AttributePropertyHint::KEYWORD, + AttributePropertyDebug::KEYWORD, ", ", AttributePropertyEnabledMarker::KEYWORD_ON, ", ", AttributePropertyEnabledMarker::KEYWORD_OFF, ".", @@ -766,9 +766,9 @@ impl syn::parse::Parse for FieldAttributeConfig let ident : syn::Ident = input.parse()?; match ident.to_string().as_str() { + AttributePropertyDebug::KEYWORD => result.assign( AttributePropertyDebug::from( true ) ), AttributePropertyEnabledMarker::KEYWORD_ON => result.assign( AttributePropertyEnabled::from( true ) ), AttributePropertyEnabledMarker::KEYWORD_OFF => result.assign( AttributePropertyEnabled::from( false ) ), - AttributePropertyHint::KEYWORD => result.assign( AttributePropertyHint::parse( input )? ), _ => return Err( error( &ident ) ), } } @@ -790,19 +790,19 @@ impl syn::parse::Parse for FieldAttributeConfig // == attribute properties -/// Marker type for attribute property to specify whether to provide a sketch as a hint. -/// Defaults to `false`, which means no hint is provided unless explicitly requested. +/// Marker type for attribute property to specify whether to provide a generated code as a hint. +/// Defaults to `false`, which means no debug is provided unless explicitly requested. #[ derive( Debug, Default, Clone, Copy ) ] -pub struct AttributePropertyHintMarker; +pub struct AttributePropertyDebugMarker; -impl AttributePropertyComponent for AttributePropertyHintMarker +impl AttributePropertyComponent for AttributePropertyDebugMarker { - const KEYWORD : &'static str = "hint"; + const KEYWORD : &'static str = "debug"; } -/// Specifies whether to provide a sketch as a hint. -/// Defaults to `false`, which means no hint is provided unless explicitly requested. -pub type AttributePropertyHint = AttributePropertyBoolean< AttributePropertyHintMarker >; +/// Specifies whether to provide a generated code as a hint. +/// Defaults to `false`, which means no debug is provided unless explicitly requested. +pub type AttributePropertyDebug = AttributePropertySingletone< AttributePropertyDebugMarker >; // = diff --git a/module/core/former_meta/src/derive_former/field_attrs.rs b/module/core/former_meta/src/derive_former/field_attrs.rs index 93b1b1a267..9ed0b1559b 100644 --- a/module/core/former_meta/src/derive_former/field_attrs.rs +++ b/module/core/former_meta/src/derive_former/field_attrs.rs @@ -235,7 +235,7 @@ pub struct AttributeScalarSetter pub setter : AttributePropertySetter, /// Specifies whether to provide a sketch of the subform setter as a hint. /// Defaults to `false`, which means no hint is provided unless explicitly requested. - pub hint : AttributePropertyHint, + pub hint : AttributePropertyDebug, } impl AttributeScalarSetter @@ -306,9 +306,9 @@ where } } -impl< IntoT > ComponentAssign< AttributePropertyHint, IntoT > for AttributeScalarSetter +impl< IntoT > ComponentAssign< AttributePropertyDebug, IntoT > for AttributeScalarSetter where - IntoT : Into< AttributePropertyHint >, + IntoT : Into< AttributePropertyDebug >, { #[ inline( always ) ] fn assign( &mut self, component : IntoT ) @@ -330,7 +330,7 @@ impl syn::parse::Parse for AttributeScalarSetter "Known entries of attribute ", AttributeScalarSetter::KEYWORD, " are : ", AttributePropertyName::KEYWORD, ", ", AttributePropertySetter::KEYWORD, - ", ", AttributePropertyHint::KEYWORD, + ", ", AttributePropertyDebug::KEYWORD, ".", ); syn_err! @@ -354,7 +354,7 @@ impl syn::parse::Parse for AttributeScalarSetter { AttributePropertyName::KEYWORD => result.assign( AttributePropertyName::parse( input )? ), AttributePropertySetter::KEYWORD => result.assign( AttributePropertySetter::parse( input )? ), - AttributePropertyHint::KEYWORD => result.assign( AttributePropertyHint::parse( input )? ), + AttributePropertyDebug::KEYWORD => result.assign( AttributePropertyDebug::parse( input )? ), _ => return Err( error( &ident ) ), } } @@ -396,7 +396,7 @@ pub struct AttributeSubformScalarSetter pub setter : AttributePropertySetter, /// Specifies whether to provide a sketch of the subform setter as a hint. /// Defaults to `false`, which means no hint is provided unless explicitly requested. - pub hint : AttributePropertyHint, + pub hint : AttributePropertyDebug, } impl AttributeSubformScalarSetter @@ -466,9 +466,9 @@ where } } -impl< IntoT > ComponentAssign< AttributePropertyHint, IntoT > for AttributeSubformScalarSetter +impl< IntoT > ComponentAssign< AttributePropertyDebug, IntoT > for AttributeSubformScalarSetter where - IntoT : Into< AttributePropertyHint >, + IntoT : Into< AttributePropertyDebug >, { #[ inline( always ) ] fn assign( &mut self, component : IntoT ) @@ -490,7 +490,7 @@ impl syn::parse::Parse for AttributeSubformScalarSetter "Known entries of attribute ", AttributeSubformScalarSetter::KEYWORD, " are : ", AttributePropertyName::KEYWORD, ", ", AttributePropertySetter::KEYWORD, - ", ", AttributePropertyHint::KEYWORD, + ", ", AttributePropertyDebug::KEYWORD, ".", ); syn_err! @@ -514,7 +514,7 @@ impl syn::parse::Parse for AttributeSubformScalarSetter { AttributePropertyName::KEYWORD => result.assign( AttributePropertyName::parse( input )? ), AttributePropertySetter::KEYWORD => result.assign( AttributePropertySetter::parse( input )? ), - AttributePropertyHint::KEYWORD => result.assign( AttributePropertyHint::parse( input )? ), + AttributePropertyDebug::KEYWORD => result.assign( AttributePropertyDebug::parse( input )? ), _ => return Err( error( &ident ) ), } } @@ -556,7 +556,7 @@ pub struct AttributeSubformCollectionSetter pub setter : AttributePropertySetter, /// Specifies whether to provide a sketch of the subform setter as a hint. /// Defaults to `false`, which means no hint is provided unless explicitly requested. - pub hint : AttributePropertyHint, + pub hint : AttributePropertyDebug, /// Definition of the collection former to use, e.g., `former::VectorFormer`. pub definition : AttributePropertyDefinition, } @@ -639,9 +639,9 @@ where } } -impl< IntoT > ComponentAssign< AttributePropertyHint, IntoT > for AttributeSubformCollectionSetter +impl< IntoT > ComponentAssign< AttributePropertyDebug, IntoT > for AttributeSubformCollectionSetter where - IntoT : Into< AttributePropertyHint >, + IntoT : Into< AttributePropertyDebug >, { #[ inline( always ) ] fn assign( &mut self, component : IntoT ) @@ -663,7 +663,7 @@ impl syn::parse::Parse for AttributeSubformCollectionSetter "Known entries of attribute ", AttributeSubformCollectionSetter::KEYWORD, " are : ", AttributePropertyName::KEYWORD, ", ", AttributePropertySetter::KEYWORD, - ", ", AttributePropertyHint::KEYWORD, + ", ", AttributePropertyDebug::KEYWORD, ", ", AttributePropertyDefinition::KEYWORD, ".", ); @@ -688,7 +688,7 @@ impl syn::parse::Parse for AttributeSubformCollectionSetter { AttributePropertyName::KEYWORD => result.assign( AttributePropertyName::parse( input )? ), AttributePropertySetter::KEYWORD => result.assign( AttributePropertySetter::parse( input )? ), - AttributePropertyHint::KEYWORD => result.assign( AttributePropertyHint::parse( input )? ), + AttributePropertyDebug::KEYWORD => result.assign( AttributePropertyDebug::parse( input )? ), AttributePropertyDefinition::KEYWORD => result.assign( AttributePropertyDefinition::parse( input )? ), _ => return Err( error( &ident ) ), } @@ -738,7 +738,7 @@ pub struct AttributeSubformEntrySetter pub setter : AttributePropertySetter, /// Specifies whether to provide a sketch of the subform setter as a hint. /// Defaults to `false`, which means no hint is provided unless explicitly requested. - pub hint : AttributePropertyHint, + pub hint : AttributePropertyDebug, } impl AttributeSubformEntrySetter @@ -808,9 +808,9 @@ where } } -impl< IntoT > ComponentAssign< AttributePropertyHint, IntoT > for AttributeSubformEntrySetter +impl< IntoT > ComponentAssign< AttributePropertyDebug, IntoT > for AttributeSubformEntrySetter where - IntoT : Into< AttributePropertyHint >, + IntoT : Into< AttributePropertyDebug >, { #[ inline( always ) ] fn assign( &mut self, component : IntoT ) @@ -832,7 +832,7 @@ impl syn::parse::Parse for AttributeSubformEntrySetter "Known entries of attribute ", AttributeSubformEntrySetter::KEYWORD, " are : ", AttributePropertyName::KEYWORD, ", ", AttributePropertySetter::KEYWORD, - ", ", AttributePropertyHint::KEYWORD, + ", ", AttributePropertyDebug::KEYWORD, ".", ); syn_err! @@ -856,7 +856,7 @@ impl syn::parse::Parse for AttributeSubformEntrySetter { AttributePropertyName::KEYWORD => result.assign( AttributePropertyName::parse( input )? ), AttributePropertySetter::KEYWORD => result.assign( AttributePropertySetter::parse( input )? ), - AttributePropertyHint::KEYWORD => result.assign( AttributePropertyHint::parse( input )? ), + AttributePropertyDebug::KEYWORD => result.assign( AttributePropertyDebug::parse( input )? ), _ => return Err( error( &ident ) ), } } @@ -883,18 +883,18 @@ impl syn::parse::Parse for AttributeSubformEntrySetter /// Marker type for attribute property to specify whether to provide a sketch as a hint. /// Defaults to `false`, which means no hint is provided unless explicitly requested. #[ derive( Debug, Default, Clone, Copy ) ] -pub struct AttributePropertyHintMarker; +pub struct AttributePropertyDebugMarker; /// Specifies whether to provide a sketch as a hint. /// Defaults to `false`, which means no hint is provided unless explicitly requested. -impl AttributePropertyComponent for AttributePropertyHintMarker +impl AttributePropertyComponent for AttributePropertyDebugMarker { const KEYWORD : &'static str = "hint"; } /// Specifies whether to provide a sketch as a hint. /// Defaults to `false`, which means no hint is provided unless explicitly requested. -pub type AttributePropertyHint = AttributePropertyBoolean< AttributePropertyHintMarker >; +pub type AttributePropertyDebug = AttributePropertySingletone< AttributePropertyDebugMarker >; // = diff --git a/module/core/former_meta/src/derive_former/struct_attrs.rs b/module/core/former_meta/src/derive_former/struct_attrs.rs index 014e304f8a..54570551f5 100644 --- a/module/core/former_meta/src/derive_former/struct_attrs.rs +++ b/module/core/former_meta/src/derive_former/struct_attrs.rs @@ -243,7 +243,7 @@ pub struct AttributeMutator pub custom : AttributePropertyCustom, /// Specifies whether to provide a sketch of the mutator as a hint. /// Defaults to `false`, which means no hint is provided unless explicitly requested. - pub hint : AttributePropertyHint, + pub hint : AttributePropertyDebug, // qqq : xxx : use the property. currently it's not used } @@ -280,9 +280,9 @@ where } } -impl< IntoT > ComponentAssign< AttributePropertyHint, IntoT > for AttributeMutator +impl< IntoT > ComponentAssign< AttributePropertyDebug, IntoT > for AttributeMutator where - IntoT : Into< AttributePropertyHint >, + IntoT : Into< AttributePropertyDebug >, { #[ inline( always ) ] fn assign( &mut self, component : IntoT ) @@ -314,7 +314,7 @@ impl syn::parse::Parse for AttributeMutator ( "Known entries of attribute ", AttributeMutator::KEYWORD, " are : ", AttributePropertyCustom::KEYWORD, - ", ", AttributePropertyHint::KEYWORD, + ", ", AttributePropertyDebug::KEYWORD, ".", ); syn_err! @@ -337,7 +337,7 @@ impl syn::parse::Parse for AttributeMutator match ident.to_string().as_str() { AttributePropertyCustom::KEYWORD => result.assign( AttributePropertyCustom::parse( input )? ), - AttributePropertyHint::KEYWORD => result.assign( AttributePropertyHint::parse( input )? ), + AttributePropertyDebug::KEYWORD => result.assign( AttributePropertyDebug::parse( input )? ), _ => return Err( error( &ident ) ), } } @@ -416,16 +416,16 @@ where /// Marker type for attribute property to specify whether to provide a sketch as a hint. /// Defaults to `false`, which means no hint is provided unless explicitly requested. #[ derive( Debug, Default, Clone, Copy ) ] -pub struct AttributePropertyHintMarker; +pub struct AttributePropertyDebugMarker; -impl AttributePropertyComponent for AttributePropertyHintMarker +impl AttributePropertyComponent for AttributePropertyDebugMarker { const KEYWORD : &'static str = "hint"; } /// Specifies whether to provide a sketch as a hint. /// Defaults to `false`, which means no hint is provided unless explicitly requested. -pub type AttributePropertyHint = AttributePropertyBoolean< AttributePropertyHintMarker >; +pub type AttributePropertyDebug = AttributePropertySingletone< AttributePropertyDebugMarker >; // = diff --git a/module/core/macro_tools/Readme.md b/module/core/macro_tools/Readme.md index 3d805ccdd9..5a0e66961e 100644 --- a/module/core/macro_tools/Readme.md +++ b/module/core/macro_tools/Readme.md @@ -170,7 +170,7 @@ fn main() pub custom : AttributePropertyCustom, /// Specifies whether to provide a sketch of the mutator as a hint. /// Defaults to `false`, which means no hint is provided unless explicitly requested. - pub hint : AttributePropertyHint, + pub hint : AttributePropertyDebug, } impl AttributeComponent for AttributeMutator @@ -212,10 +212,10 @@ fn main() } } - // Implement `ComponentAssign` trait to allow assigning `AttributePropertyHint` to `AttributeMutator`. - impl< IntoT > ComponentAssign< AttributePropertyHint, IntoT > for AttributeMutator + // Implement `ComponentAssign` trait to allow assigning `AttributePropertyDebug` to `AttributeMutator`. + impl< IntoT > ComponentAssign< AttributePropertyDebug, IntoT > for AttributeMutator where - IntoT : Into< AttributePropertyHint >, + IntoT : Into< AttributePropertyDebug >, { #[ inline( always ) ] fn assign( & mut self, component : IntoT ) @@ -248,7 +248,7 @@ fn main() ( "Known entries of attribute ", AttributeMutator::KEYWORD, " are: ", AttributePropertyCustom::KEYWORD, - ", ", AttributePropertyHint::KEYWORD, + ", ", AttributePropertyDebug::KEYWORD, "." ); syn_err! @@ -272,7 +272,7 @@ fn main() match ident.to_string().as_str() { AttributePropertyCustom::KEYWORD => result.assign( AttributePropertyCustom::parse( input )? ), - AttributePropertyHint::KEYWORD => result.assign( AttributePropertyHint::parse( input )? ), + AttributePropertyDebug::KEYWORD => result.assign( AttributePropertyDebug::parse( input )? ), _ => return Err( error( & ident ) ), } } @@ -297,16 +297,16 @@ fn main() /// Marker type for attribute property to specify whether to provide a sketch as a hint. /// Defaults to `false`, which means no hint is provided unless explicitly requested. #[ derive( Debug, Default, Clone, Copy ) ] - pub struct AttributePropertyHintMarker; + pub struct AttributePropertyDebugMarker; - impl AttributePropertyComponent for AttributePropertyHintMarker + impl AttributePropertyComponent for AttributePropertyDebugMarker { const KEYWORD : & 'static str = "hint"; } /// Specifies whether to provide a sketch as a hint. /// Defaults to `false`, which means no hint is provided unless explicitly requested. - pub type AttributePropertyHint = AttributePropertyBoolean< AttributePropertyHintMarker >; + pub type AttributePropertyDebug = AttributePropertySingletone< AttributePropertyDebugMarker >; // == @@ -332,11 +332,11 @@ fn main() println!( "{:?}", attrs ); // Test `AttributePropertyBoolean` functionality. - let attr : AttributePropertyBoolean< AttributePropertyHintMarker > = AttributePropertyBoolean::default(); + let attr : AttributePropertyBoolean< AttributePropertyDebugMarker > = AttributePropertyBoolean::default(); assert_eq!( attr.internal(), false ); - let attr : AttributePropertyBoolean< AttributePropertyHintMarker > = true.into(); + let attr : AttributePropertyBoolean< AttributePropertyDebugMarker > = true.into(); assert_eq!( attr.internal(), true ); - let attr : AttributePropertyBoolean< AttributePropertyHintMarker > = false.into(); + let attr : AttributePropertyBoolean< AttributePropertyDebugMarker > = false.into(); assert_eq!( attr.internal(), false ); } diff --git a/module/core/macro_tools/examples/macro_tools_attr_prop.rs b/module/core/macro_tools/examples/macro_tools_attr_prop.rs index b8284bce50..073f1bf374 100644 --- a/module/core/macro_tools/examples/macro_tools_attr_prop.rs +++ b/module/core/macro_tools/examples/macro_tools_attr_prop.rs @@ -106,7 +106,7 @@ fn main() /// ## Example of code /// /// ```ignore - /// #[ mutator( custom = true, hint = true ) ] + /// #[ mutator( custom = true, debug = true ) ] /// ``` #[ derive( Debug, Default ) ] pub struct AttributeMutator @@ -114,9 +114,9 @@ fn main() /// Indicates whether a custom mutator should be generated. /// Defaults to `false`, meaning no custom mutator is generated unless explicitly requested. pub custom : AttributePropertyCustom, - /// Specifies whether to provide a sketch of the mutator as a hint. + /// Specifies whether to print code generated for the field. /// Defaults to `false`, which means no hint is provided unless explicitly requested. - pub hint : AttributePropertyHint, + pub debug : AttributePropertyDebug, } impl AttributeComponent for AttributeMutator @@ -158,10 +158,10 @@ fn main() } } - // Implement `ComponentAssign` trait to allow assigning `AttributePropertyHint` to `AttributeMutator`. - impl< IntoT > ComponentAssign< AttributePropertyHint, IntoT > for AttributeMutator + // Implement `ComponentAssign` trait to allow assigning `AttributePropertyDebug` to `AttributeMutator`. + impl< IntoT > ComponentAssign< AttributePropertyDebug, IntoT > for AttributeMutator where - IntoT : Into< AttributePropertyHint >, + IntoT : Into< AttributePropertyDebug >, { #[ inline( always ) ] fn assign( & mut self, component : IntoT ) @@ -194,7 +194,7 @@ fn main() ( "Known entries of attribute ", AttributeMutator::KEYWORD, " are: ", AttributePropertyCustom::KEYWORD, - ", ", AttributePropertyHint::KEYWORD, + ", ", AttributePropertyDebug::KEYWORD, "." ); syn_err! @@ -218,7 +218,7 @@ fn main() match ident.to_string().as_str() { AttributePropertyCustom::KEYWORD => result.assign( AttributePropertyCustom::parse( input )? ), - AttributePropertyHint::KEYWORD => result.assign( AttributePropertyHint::parse( input )? ), + AttributePropertyDebug::KEYWORD => result.assign( AttributePropertyDebug::parse( input )? ), _ => return Err( error( & ident ) ), } } @@ -243,16 +243,16 @@ fn main() /// Marker type for attribute property to specify whether to provide a sketch as a hint. /// Defaults to `false`, which means no hint is provided unless explicitly requested. #[ derive( Debug, Default, Clone, Copy ) ] - pub struct AttributePropertyHintMarker; + pub struct AttributePropertyDebugMarker; - impl AttributePropertyComponent for AttributePropertyHintMarker + impl AttributePropertyComponent for AttributePropertyDebugMarker { - const KEYWORD : & 'static str = "hint"; + const KEYWORD : & 'static str = "debug"; } /// Specifies whether to provide a sketch as a hint. /// Defaults to `false`, which means no hint is provided unless explicitly requested. - pub type AttributePropertyHint = AttributePropertyBoolean< AttributePropertyHintMarker >; + pub type AttributePropertyDebug = AttributePropertySingletone< AttributePropertyDebugMarker >; // == @@ -278,11 +278,11 @@ fn main() println!( "{:?}", attrs ); // Test `AttributePropertyBoolean` functionality. - let attr : AttributePropertyBoolean< AttributePropertyHintMarker > = AttributePropertyBoolean::default(); + let attr : AttributePropertyBoolean< AttributePropertyDebugMarker > = AttributePropertyBoolean::default(); assert_eq!( attr.internal(), false ); - let attr : AttributePropertyBoolean< AttributePropertyHintMarker > = true.into(); + let attr : AttributePropertyBoolean< AttributePropertyDebugMarker > = true.into(); assert_eq!( attr.internal(), true ); - let attr : AttributePropertyBoolean< AttributePropertyHintMarker > = false.into(); + let attr : AttributePropertyBoolean< AttributePropertyDebugMarker > = false.into(); assert_eq!( attr.internal(), false ); } From b831eab0611f1b68c1cb4a5fcd50667e54858a77 Mon Sep 17 00:00:00 2001 From: wandalen Date: Wed, 29 May 2024 00:23:17 +0300 Subject: [PATCH 16/59] former : property hint - --- module/core/derive_tools_meta/src/derive/from.rs | 2 +- module/core/former/Readme.md | 8 ++++---- .../former/examples/former_custom_scalar_setter.rs | 2 +- .../examples/former_custom_setter_overriden.rs | 2 +- .../examples/former_custom_subform_collection.rs | 2 +- .../former/examples/former_custom_subform_entry.rs | 2 +- .../former/examples/former_custom_subform_entry2.rs | 2 +- .../former_meta/src/derive_former/field_attrs.rs | 13 +++++++------ .../former_meta/src/derive_former/struct_attrs.rs | 13 ++++++++----- module/core/macro_tools/Readme.md | 6 +++--- .../macro_tools/examples/macro_tools_attr_prop.rs | 5 +++-- 11 files changed, 31 insertions(+), 26 deletions(-) diff --git a/module/core/derive_tools_meta/src/derive/from.rs b/module/core/derive_tools_meta/src/derive/from.rs index 6ad6079288..2b4b06c6c5 100644 --- a/module/core/derive_tools_meta/src/derive/from.rs +++ b/module/core/derive_tools_meta/src/derive/from.rs @@ -692,7 +692,7 @@ impl AttributeComponent for FieldAttributeConfig { return Ok( Default::default() ) }, - _ => return_syn_err!( attr, "Expects an attribute of format `#[ from( on, hint = true ) ]`. \nGot: {}", qt!{ #attr } ), + _ => return_syn_err!( attr, "Expects an attribute of format `#[ from( on, debug ) ]`. \nGot: {}", qt!{ #attr } ), } } diff --git a/module/core/former/Readme.md b/module/core/former/Readme.md index 56ff1102b5..342cd3a74a 100644 --- a/module/core/former/Readme.md +++ b/module/core/former/Readme.md @@ -539,7 +539,7 @@ But it's also possible to completely override setter and write its own from scra #[ derive( Debug, Former ) ] pub struct StructWithCustomSetters { - // Use `hint = true` to gennerate sketch of setter. + // Use `debug` to gennerate sketch of setter. #[ scalar( setter = false, hint = false ) ] word : String, } @@ -812,7 +812,7 @@ The `child` function within `ParentFormer` is a custom subform setter that plays // #[ debug ] pub struct Parent { - // Use `hint = true` to gennerate sketch of setter. + // Use `debug` to gennerate sketch of setter. #[ scalar( setter = false, hint = false ) ] children : HashMap< String, Child >, } @@ -974,7 +974,7 @@ The `child` function within `ParentFormer` is a custom subform setter that plays // #[ debug ] pub struct Parent { - // Use `hint = true` to gennerate sketch of setter. + // Use `debug` to gennerate sketch of setter. #[ scalar( setter = false, hint = false ) ] children : HashMap< String, Child >, } @@ -1055,7 +1055,7 @@ The `child` function within `ParentFormer` is a custom subform setter that plays // #[ debug ] pub struct Parent { - // Use `hint = true` to gennerate sketch of setter. + // Use `debug` to gennerate sketch of setter. #[ subform_entry( setter = false, hint = false ) ] child : HashMap< String, Child >, } diff --git a/module/core/former/examples/former_custom_scalar_setter.rs b/module/core/former/examples/former_custom_scalar_setter.rs index ce0588352e..1918db1098 100644 --- a/module/core/former/examples/former_custom_scalar_setter.rs +++ b/module/core/former/examples/former_custom_scalar_setter.rs @@ -47,7 +47,7 @@ fn main() // #[ debug ] pub struct Parent { - // Use `hint = true` to gennerate sketch of setter. + // Use `debug` to gennerate sketch of setter. #[ scalar( setter = false, hint = false ) ] children : HashMap< String, Child >, } diff --git a/module/core/former/examples/former_custom_setter_overriden.rs b/module/core/former/examples/former_custom_setter_overriden.rs index 08acd738a0..72b2d40eb7 100644 --- a/module/core/former/examples/former_custom_setter_overriden.rs +++ b/module/core/former/examples/former_custom_setter_overriden.rs @@ -18,7 +18,7 @@ fn main() #[ derive( Debug, Former ) ] pub struct StructWithCustomSetters { - // Use `hint = true` to gennerate sketch of setter. + // Use `debug` to gennerate sketch of setter. #[ scalar( setter = false, hint = false ) ] word : String, } diff --git a/module/core/former/examples/former_custom_subform_collection.rs b/module/core/former/examples/former_custom_subform_collection.rs index 963431d27a..f69d3f2bd9 100644 --- a/module/core/former/examples/former_custom_subform_collection.rs +++ b/module/core/former/examples/former_custom_subform_collection.rs @@ -47,7 +47,7 @@ fn main() // #[ debug ] pub struct Parent { - // Use `hint = true` to gennerate sketch of setter. + // Use `debug` to gennerate sketch of setter. #[ subform_collection( setter = false, hint = false ) ] children : HashMap< String, Child >, } diff --git a/module/core/former/examples/former_custom_subform_entry.rs b/module/core/former/examples/former_custom_subform_entry.rs index 865282012f..6b1b4f7894 100644 --- a/module/core/former/examples/former_custom_subform_entry.rs +++ b/module/core/former/examples/former_custom_subform_entry.rs @@ -47,7 +47,7 @@ fn main() // #[ debug ] pub struct Parent { - // Use `hint = true` to gennerate sketch of setter. + // Use `debug` to gennerate sketch of setter. #[ subform_entry( setter = false, hint = false ) ] child : HashMap< String, Child >, } diff --git a/module/core/former/examples/former_custom_subform_entry2.rs b/module/core/former/examples/former_custom_subform_entry2.rs index d3eebbab21..ba9bc7138a 100644 --- a/module/core/former/examples/former_custom_subform_entry2.rs +++ b/module/core/former/examples/former_custom_subform_entry2.rs @@ -47,7 +47,7 @@ fn main() // #[ debug ] pub struct Parent { - // Use `hint = true` to gennerate sketch of setter. + // Use `debug` to gennerate sketch of setter. #[ subform_entry( setter = false, hint = false ) ] child : HashMap< String, Child >, } diff --git a/module/core/former_meta/src/derive_former/field_attrs.rs b/module/core/former_meta/src/derive_former/field_attrs.rs index 9ed0b1559b..55ebccd88e 100644 --- a/module/core/former_meta/src/derive_former/field_attrs.rs +++ b/module/core/former_meta/src/derive_former/field_attrs.rs @@ -10,6 +10,7 @@ use macro_tools:: AttributePropertyBoolean, AttributePropertyOptionalBoolean, AttributePropertyOptionalSyn, + AttributePropertySingletone, }; use former_types::{ ComponentAssign }; @@ -354,7 +355,7 @@ impl syn::parse::Parse for AttributeScalarSetter { AttributePropertyName::KEYWORD => result.assign( AttributePropertyName::parse( input )? ), AttributePropertySetter::KEYWORD => result.assign( AttributePropertySetter::parse( input )? ), - AttributePropertyDebug::KEYWORD => result.assign( AttributePropertyDebug::parse( input )? ), + AttributePropertyDebug::KEYWORD => result.assign( AttributePropertyDebug::from( true ) ), _ => return Err( error( &ident ) ), } } @@ -514,7 +515,7 @@ impl syn::parse::Parse for AttributeSubformScalarSetter { AttributePropertyName::KEYWORD => result.assign( AttributePropertyName::parse( input )? ), AttributePropertySetter::KEYWORD => result.assign( AttributePropertySetter::parse( input )? ), - AttributePropertyDebug::KEYWORD => result.assign( AttributePropertyDebug::parse( input )? ), + AttributePropertyDebug::KEYWORD => result.assign( AttributePropertyDebug::from( true ) ), _ => return Err( error( &ident ) ), } } @@ -556,7 +557,7 @@ pub struct AttributeSubformCollectionSetter pub setter : AttributePropertySetter, /// Specifies whether to provide a sketch of the subform setter as a hint. /// Defaults to `false`, which means no hint is provided unless explicitly requested. - pub hint : AttributePropertyDebug, + pub debug : AttributePropertyDebug, /// Definition of the collection former to use, e.g., `former::VectorFormer`. pub definition : AttributePropertyDefinition, } @@ -688,7 +689,7 @@ impl syn::parse::Parse for AttributeSubformCollectionSetter { AttributePropertyName::KEYWORD => result.assign( AttributePropertyName::parse( input )? ), AttributePropertySetter::KEYWORD => result.assign( AttributePropertySetter::parse( input )? ), - AttributePropertyDebug::KEYWORD => result.assign( AttributePropertyDebug::parse( input )? ), + AttributePropertyDebug::KEYWORD => result.assign( AttributePropertyDebug::from( true ) ), AttributePropertyDefinition::KEYWORD => result.assign( AttributePropertyDefinition::parse( input )? ), _ => return Err( error( &ident ) ), } @@ -856,7 +857,7 @@ impl syn::parse::Parse for AttributeSubformEntrySetter { AttributePropertyName::KEYWORD => result.assign( AttributePropertyName::parse( input )? ), AttributePropertySetter::KEYWORD => result.assign( AttributePropertySetter::parse( input )? ), - AttributePropertyDebug::KEYWORD => result.assign( AttributePropertyDebug::parse( input )? ), + AttributePropertyDebug::KEYWORD => result.assign( AttributePropertyDebug::from( true ) ), _ => return Err( error( &ident ) ), } } @@ -889,7 +890,7 @@ pub struct AttributePropertyDebugMarker; /// Defaults to `false`, which means no hint is provided unless explicitly requested. impl AttributePropertyComponent for AttributePropertyDebugMarker { - const KEYWORD : &'static str = "hint"; + const KEYWORD : &'static str = "debug"; } /// Specifies whether to provide a sketch as a hint. diff --git a/module/core/former_meta/src/derive_former/struct_attrs.rs b/module/core/former_meta/src/derive_former/struct_attrs.rs index 54570551f5..b8db7a8163 100644 --- a/module/core/former_meta/src/derive_former/struct_attrs.rs +++ b/module/core/former_meta/src/derive_former/struct_attrs.rs @@ -11,6 +11,7 @@ use macro_tools:: AttributeComponent, AttributePropertyComponent, AttributePropertyBoolean, + AttributePropertySingletone, }; use former_types::{ ComponentAssign }; @@ -232,9 +233,11 @@ impl syn::parse::Parse for AttributeStorageFields /// /// ## Example of code /// ```ignore -/// custom = true, hint = true +/// custom = true, debug /// ``` +// xxx + #[ derive( Debug, Default ) ] pub struct AttributeMutator { @@ -243,7 +246,7 @@ pub struct AttributeMutator pub custom : AttributePropertyCustom, /// Specifies whether to provide a sketch of the mutator as a hint. /// Defaults to `false`, which means no hint is provided unless explicitly requested. - pub hint : AttributePropertyDebug, + pub debug : AttributePropertyDebug, // qqq : xxx : use the property. currently it's not used } @@ -263,7 +266,7 @@ impl AttributeComponent for AttributeMutator { return Ok( Default::default() ) }, - _ => return_syn_err!( attr, "Expects an attribute of format `#[ mutator( custom = true, hint = true ) ]`. \nGot: {}", qt!{ #attr } ), + _ => return_syn_err!( attr, "Expects an attribute of format `#[ mutator( custom = true, debug ) ]`. \nGot: {}", qt!{ #attr } ), } } @@ -337,7 +340,7 @@ impl syn::parse::Parse for AttributeMutator match ident.to_string().as_str() { AttributePropertyCustom::KEYWORD => result.assign( AttributePropertyCustom::parse( input )? ), - AttributePropertyDebug::KEYWORD => result.assign( AttributePropertyDebug::parse( input )? ), + AttributePropertyDebug::KEYWORD => result.assign( AttributePropertyDebug::from( true ) ), _ => return Err( error( &ident ) ), } } @@ -420,7 +423,7 @@ pub struct AttributePropertyDebugMarker; impl AttributePropertyComponent for AttributePropertyDebugMarker { - const KEYWORD : &'static str = "hint"; + const KEYWORD : &'static str = "debug"; } /// Specifies whether to provide a sketch as a hint. diff --git a/module/core/macro_tools/Readme.md b/module/core/macro_tools/Readme.md index 5a0e66961e..9a9b8f9c1a 100644 --- a/module/core/macro_tools/Readme.md +++ b/module/core/macro_tools/Readme.md @@ -160,7 +160,7 @@ fn main() /// ## Example of code /// /// ```ignore - /// #[ mutator( custom = true, hint = true ) ] + /// #[ mutator( custom = true, debug ) ] /// ``` #[ derive( Debug, Default ) ] pub struct AttributeMutator @@ -193,7 +193,7 @@ fn main() _ => return_syn_err! ( attr, - "Expects an attribute of format `#[ mutator( custom = true, hint = true ) ]`. \nGot: {}", + "Expects an attribute of format `#[ mutator( custom = true, debug ) ]`. \nGot: {}", qt! { #attr } ), } @@ -272,7 +272,7 @@ fn main() match ident.to_string().as_str() { AttributePropertyCustom::KEYWORD => result.assign( AttributePropertyCustom::parse( input )? ), - AttributePropertyDebug::KEYWORD => result.assign( AttributePropertyDebug::parse( input )? ), + AttributePropertyDebug::KEYWORD => result.assign( AttributePropertyDebug::from( true ) ), _ => return Err( error( & ident ) ), } } diff --git a/module/core/macro_tools/examples/macro_tools_attr_prop.rs b/module/core/macro_tools/examples/macro_tools_attr_prop.rs index 073f1bf374..dafd08a371 100644 --- a/module/core/macro_tools/examples/macro_tools_attr_prop.rs +++ b/module/core/macro_tools/examples/macro_tools_attr_prop.rs @@ -139,7 +139,8 @@ fn main() _ => return_syn_err! ( attr, - "Expects an attribute of format `#[ mutator( custom = true, hint = true ) ]`. \nGot: {}", + "Expects an attribute of format `#[ mutator( custom = true, debug ) ]`. \nGot: {}", + // xxx : just custom qt! { #attr } ), } @@ -218,7 +219,7 @@ fn main() match ident.to_string().as_str() { AttributePropertyCustom::KEYWORD => result.assign( AttributePropertyCustom::parse( input )? ), - AttributePropertyDebug::KEYWORD => result.assign( AttributePropertyDebug::parse( input )? ), + AttributePropertyDebug::KEYWORD => result.assign( AttributePropertyDebug::from( true ) ), _ => return Err( error( & ident ) ), } } From 989e9fded4bb2fa19bfae69246293434bce2a6f0 Mon Sep 17 00:00:00 2001 From: wandalen Date: Wed, 29 May 2024 00:24:10 +0300 Subject: [PATCH 17/59] former : property hint - --- module/core/derive_tools_meta/src/derive/from.rs | 2 +- module/core/former/Readme.md | 10 +++++----- .../former/examples/former_custom_scalar_setter.rs | 2 +- .../former/examples/former_custom_setter_overriden.rs | 2 +- .../examples/former_custom_subform_collection.rs | 2 +- .../former/examples/former_custom_subform_entry.rs | 2 +- .../former/examples/former_custom_subform_entry2.rs | 2 +- .../former/examples/former_custom_subform_scalar.rs | 2 +- .../core/former_meta/src/derive_former/field_attrs.rs | 8 ++++---- .../core/former_meta/src/derive_former/struct_attrs.rs | 2 +- module/core/macro_tools/Readme.md | 4 ++-- .../core/macro_tools/examples/macro_tools_attr_prop.rs | 4 ++-- module/move/wca/src/ca/aggregator.rs | 2 +- module/move/wca/src/ca/grammar/dictionary.rs | 4 ++-- module/move/willbe/src/entity/package.rs | 4 ++-- module/move/willbe/src/tool/template.rs | 2 +- 16 files changed, 27 insertions(+), 27 deletions(-) diff --git a/module/core/derive_tools_meta/src/derive/from.rs b/module/core/derive_tools_meta/src/derive/from.rs index 2b4b06c6c5..4c75af6a75 100644 --- a/module/core/derive_tools_meta/src/derive/from.rs +++ b/module/core/derive_tools_meta/src/derive/from.rs @@ -750,7 +750,7 @@ impl syn::parse::Parse for FieldAttributeConfig syn_err! ( ident, - r#"Expects an attribute of format '#[ from( on, hint = false ) ]' + r#"Expects an attribute of format '#[ from( on, hint ) ]' {known} But got: '{}' "#, diff --git a/module/core/former/Readme.md b/module/core/former/Readme.md index 342cd3a74a..547f9575a3 100644 --- a/module/core/former/Readme.md +++ b/module/core/former/Readme.md @@ -540,7 +540,7 @@ But it's also possible to completely override setter and write its own from scra pub struct StructWithCustomSetters { // Use `debug` to gennerate sketch of setter. - #[ scalar( setter = false, hint = false ) ] + #[ scalar( setter = false, hint ) ] word : String, } @@ -813,7 +813,7 @@ The `child` function within `ParentFormer` is a custom subform setter that plays pub struct Parent { // Use `debug` to gennerate sketch of setter. - #[ scalar( setter = false, hint = false ) ] + #[ scalar( setter = false, hint ) ] children : HashMap< String, Child >, } @@ -907,7 +907,7 @@ their own formers, allowing for detailed configuration within a nested builder p { // The `subform_scalar` attribute is used to specify that the 'child' field has its own former // and can be individually configured via a subform setter. This is not a collection but a single scalar entity. - #[ subform_scalar( setter = false, hint = false ) ] + #[ subform_scalar( setter = false, hint ) ] child : Child, } @@ -975,7 +975,7 @@ The `child` function within `ParentFormer` is a custom subform setter that plays pub struct Parent { // Use `debug` to gennerate sketch of setter. - #[ scalar( setter = false, hint = false ) ] + #[ scalar( setter = false, hint ) ] children : HashMap< String, Child >, } @@ -1056,7 +1056,7 @@ The `child` function within `ParentFormer` is a custom subform setter that plays pub struct Parent { // Use `debug` to gennerate sketch of setter. - #[ subform_entry( setter = false, hint = false ) ] + #[ subform_entry( setter = false, hint ) ] child : HashMap< String, Child >, } diff --git a/module/core/former/examples/former_custom_scalar_setter.rs b/module/core/former/examples/former_custom_scalar_setter.rs index 1918db1098..002ecd27a1 100644 --- a/module/core/former/examples/former_custom_scalar_setter.rs +++ b/module/core/former/examples/former_custom_scalar_setter.rs @@ -48,7 +48,7 @@ fn main() pub struct Parent { // Use `debug` to gennerate sketch of setter. - #[ scalar( setter = false, hint = false ) ] + #[ scalar( setter = false, hint ) ] children : HashMap< String, Child >, } diff --git a/module/core/former/examples/former_custom_setter_overriden.rs b/module/core/former/examples/former_custom_setter_overriden.rs index 72b2d40eb7..a09f2eb3e5 100644 --- a/module/core/former/examples/former_custom_setter_overriden.rs +++ b/module/core/former/examples/former_custom_setter_overriden.rs @@ -19,7 +19,7 @@ fn main() pub struct StructWithCustomSetters { // Use `debug` to gennerate sketch of setter. - #[ scalar( setter = false, hint = false ) ] + #[ scalar( setter = false, hint ) ] word : String, } diff --git a/module/core/former/examples/former_custom_subform_collection.rs b/module/core/former/examples/former_custom_subform_collection.rs index f69d3f2bd9..eff4d1580e 100644 --- a/module/core/former/examples/former_custom_subform_collection.rs +++ b/module/core/former/examples/former_custom_subform_collection.rs @@ -48,7 +48,7 @@ fn main() pub struct Parent { // Use `debug` to gennerate sketch of setter. - #[ subform_collection( setter = false, hint = false ) ] + #[ subform_collection( setter = false, hint ) ] children : HashMap< String, Child >, } diff --git a/module/core/former/examples/former_custom_subform_entry.rs b/module/core/former/examples/former_custom_subform_entry.rs index 6b1b4f7894..8789253101 100644 --- a/module/core/former/examples/former_custom_subform_entry.rs +++ b/module/core/former/examples/former_custom_subform_entry.rs @@ -48,7 +48,7 @@ fn main() pub struct Parent { // Use `debug` to gennerate sketch of setter. - #[ subform_entry( setter = false, hint = false ) ] + #[ subform_entry( setter = false, hint ) ] child : HashMap< String, Child >, } diff --git a/module/core/former/examples/former_custom_subform_entry2.rs b/module/core/former/examples/former_custom_subform_entry2.rs index ba9bc7138a..db0c8bd836 100644 --- a/module/core/former/examples/former_custom_subform_entry2.rs +++ b/module/core/former/examples/former_custom_subform_entry2.rs @@ -48,7 +48,7 @@ fn main() pub struct Parent { // Use `debug` to gennerate sketch of setter. - #[ subform_entry( setter = false, hint = false ) ] + #[ subform_entry( setter = false, hint ) ] child : HashMap< String, Child >, } diff --git a/module/core/former/examples/former_custom_subform_scalar.rs b/module/core/former/examples/former_custom_subform_scalar.rs index 395616579d..219ef3fa2f 100644 --- a/module/core/former/examples/former_custom_subform_scalar.rs +++ b/module/core/former/examples/former_custom_subform_scalar.rs @@ -53,7 +53,7 @@ fn main() { // The `subform_scalar` attribute is used to specify that the 'child' field has its own former // and can be individually configured via a subform setter. This is not a collection but a single scalar entity. - #[ subform_scalar( setter = false, hint = false ) ] + #[ subform_scalar( setter = false, hint ) ] child : Child, } diff --git a/module/core/former_meta/src/derive_former/field_attrs.rs b/module/core/former_meta/src/derive_former/field_attrs.rs index 55ebccd88e..8541f6fe72 100644 --- a/module/core/former_meta/src/derive_former/field_attrs.rs +++ b/module/core/former_meta/src/derive_former/field_attrs.rs @@ -337,7 +337,7 @@ impl syn::parse::Parse for AttributeScalarSetter syn_err! ( ident, - r#"Expects an attribute of format '#[ scalar( name = myName, setter = true, hint = false ) ]' + r#"Expects an attribute of format '#[ scalar( name = myName, setter = true, hint ) ]' {known} But got: '{}' "#, @@ -497,7 +497,7 @@ impl syn::parse::Parse for AttributeSubformScalarSetter syn_err! ( ident, - r#"Expects an attribute of format '#[ subform_scalar( name = myName, setter = true, hint = false ) ]' + r#"Expects an attribute of format '#[ subform_scalar( name = myName, setter = true, hint ) ]' {known} But got: '{}' "#, @@ -647,7 +647,7 @@ where #[ inline( always ) ] fn assign( &mut self, component : IntoT ) { - self.hint = component.into(); + self.debug = component.into(); } } @@ -671,7 +671,7 @@ impl syn::parse::Parse for AttributeSubformCollectionSetter syn_err! ( ident, - r#"Expects an attribute of format '#[ subform_collection( name = myName, setter = true, hint = false, definition = MyDefinition ) ]' + r#"Expects an attribute of format '#[ subform_collection( name = myName, setter = true, hint, definition = MyDefinition ) ]' {known} But got: '{}' "#, diff --git a/module/core/former_meta/src/derive_former/struct_attrs.rs b/module/core/former_meta/src/derive_former/struct_attrs.rs index b8db7a8163..646a048bb7 100644 --- a/module/core/former_meta/src/derive_former/struct_attrs.rs +++ b/module/core/former_meta/src/derive_former/struct_attrs.rs @@ -323,7 +323,7 @@ impl syn::parse::Parse for AttributeMutator syn_err! ( ident, - r#"Expects an attribute of format '#[ mutator( custom = false, hint = false ) ]' + r#"Expects an attribute of format '#[ mutator( custom = false, hint ) ]' {known} But got: '{}' "#, diff --git a/module/core/macro_tools/Readme.md b/module/core/macro_tools/Readme.md index 9a9b8f9c1a..1102ecf09c 100644 --- a/module/core/macro_tools/Readme.md +++ b/module/core/macro_tools/Readme.md @@ -254,7 +254,7 @@ fn main() syn_err! ( ident, - r#"Expects an attribute of format '#[ mutator( custom = false, hint = false ) ]' + r#"Expects an attribute of format '#[ mutator( custom = false, hint ) ]' {known} But got: '{}' "#, @@ -327,7 +327,7 @@ fn main() // == Test code // Parse an attribute and construct a `ItemAttributes` instance. - let input : syn::Attribute = syn::parse_quote!( #[ mutator( custom = true, hint = false ) ] ); + let input : syn::Attribute = syn::parse_quote!( #[ mutator( custom = true, hint ) ] ); let attrs : ItemAttributes = ItemAttributes::from_attrs( std::iter::once( & input ) ).unwrap(); println!( "{:?}", attrs ); diff --git a/module/core/macro_tools/examples/macro_tools_attr_prop.rs b/module/core/macro_tools/examples/macro_tools_attr_prop.rs index dafd08a371..6e1dd5ee7a 100644 --- a/module/core/macro_tools/examples/macro_tools_attr_prop.rs +++ b/module/core/macro_tools/examples/macro_tools_attr_prop.rs @@ -201,7 +201,7 @@ fn main() syn_err! ( ident, - r#"Expects an attribute of format '#[ mutator( custom = false, hint = false ) ]' + r#"Expects an attribute of format '#[ mutator( custom = false, hint ) ]' {known} But got: '{}' "#, @@ -274,7 +274,7 @@ fn main() // == test code // Parse an attribute and construct a `ItemAttributes` instance. - let input : syn::Attribute = syn::parse_quote!( #[ mutator( custom = true, hint = false ) ] ); + let input : syn::Attribute = syn::parse_quote!( #[ mutator( custom = true, hint ) ] ); let attrs : ItemAttributes = ItemAttributes::from_attrs( std::iter::once( & input ) ).unwrap(); println!( "{:?}", attrs ); diff --git a/module/move/wca/src/ca/aggregator.rs b/module/move/wca/src/ca/aggregator.rs index 1174de448f..976b18a559 100644 --- a/module/move/wca/src/ca/aggregator.rs +++ b/module/move/wca/src/ca/aggregator.rs @@ -111,7 +111,7 @@ pub( crate ) mod private #[ former( default = Parser ) ] parser : Parser, - #[ scalar( setter = false, hint = false ) ] + #[ scalar( setter = false, hint ) ] #[ former( default = Executor::former().form() ) ] executor : Executor, diff --git a/module/move/wca/src/ca/grammar/dictionary.rs b/module/move/wca/src/ca/grammar/dictionary.rs index a9a79d198a..69ea52ef2f 100644 --- a/module/move/wca/src/ca/grammar/dictionary.rs +++ b/module/move/wca/src/ca/grammar/dictionary.rs @@ -20,7 +20,7 @@ pub( crate ) mod private #[ derive( Debug, Default, Former, Clone ) ] pub struct Dictionary { - #[ scalar( setter = false, hint = false ) ] + #[ scalar( setter = false, hint ) ] pub( crate ) commands : HashMap< String, Command >, } @@ -67,7 +67,7 @@ pub( crate ) mod private { self.commands.get( name ) } - + /// Find commands that match a given name part. /// /// This function accepts a `name_part` parameter which is of generic type `NamePart`. diff --git a/module/move/willbe/src/entity/package.rs b/module/move/willbe/src/entity/package.rs index 3a99fe17fc..23c1f65257 100644 --- a/module/move/willbe/src/entity/package.rs +++ b/module/move/willbe/src/entity/package.rs @@ -524,7 +524,7 @@ mod private /// how to build and where to publish the package amongst other instructions. The `#[setter( false )]` /// attribute indicates that there is no setter method for the `plans` variable and it can only be modified /// within the struct. - #[ scalar( setter = false, hint = false ) ] + #[ scalar( setter = false, hint ) ] pub plans : Vec< PackagePublishInstruction >, } @@ -613,7 +613,7 @@ mod private self.storage.base_temp_dir = path; self } - + pub fn package< IntoPackage >( mut self, package : IntoPackage ) -> Self where IntoPackage : Into< Package >, diff --git a/module/move/willbe/src/tool/template.rs b/module/move/willbe/src/tool/template.rs index 44f0e4bb9e..405c1a2512 100644 --- a/module/move/willbe/src/tool/template.rs +++ b/module/move/willbe/src/tool/template.rs @@ -303,7 +303,7 @@ mod private { /// Stores all file descriptors for current template. #[ subform_entry( setter = true ) ] - #[ scalar( setter = false, hint = false ) ] + #[ scalar( setter = false, hint ) ] pub files : Vec< TemplateFileDescriptor >, } From 7aaa2a767e145d0c534098493e5f1f1357e4d416 Mon Sep 17 00:00:00 2001 From: wandalen Date: Wed, 29 May 2024 00:32:20 +0300 Subject: [PATCH 18/59] former : property hint - --- .../core/derive_tools_meta/src/derive/from.rs | 8 +++---- module/core/former/Readme.md | 10 ++++---- .../examples/former_custom_scalar_setter.rs | 2 +- .../former_custom_setter_overriden.rs | 2 +- .../former_custom_subform_collection.rs | 2 +- .../examples/former_custom_subform_entry.rs | 2 +- .../examples/former_custom_subform_entry2.rs | 2 +- .../examples/former_custom_subform_scalar.rs | 2 +- module/core/former_meta/src/derive_former.rs | 8 +++---- .../former_meta/src/derive_former/field.rs | 24 +++++++++---------- .../src/derive_former/field_attrs.rs | 19 +++++++-------- .../src/derive_former/struct_attrs.rs | 7 +++--- module/core/macro_tools/Readme.md | 12 +++++----- .../examples/macro_tools_attr_prop.rs | 8 +++---- module/core/macro_tools/src/attr_prop.rs | 2 +- .../core/macro_tools/src/attr_prop/boolean.rs | 2 +- .../macro_tools/tests/inc/attr_prop_test.rs | 4 ++-- module/move/wca/src/ca/facade.rs | 2 +- module/move/wca/src/ca/grammar/command.rs | 4 ++-- 19 files changed, 61 insertions(+), 61 deletions(-) diff --git a/module/core/derive_tools_meta/src/derive/from.rs b/module/core/derive_tools_meta/src/derive/from.rs index 4c75af6a75..471109b114 100644 --- a/module/core/derive_tools_meta/src/derive/from.rs +++ b/module/core/derive_tools_meta/src/derive/from.rs @@ -483,7 +483,7 @@ impl ItemAttributes /// Attribute to hold parameters of forming for a specific field or variant. /// For example to avoid code From generation for it. /// -/// `#[ from( on, debug ) ]` +/// `#[ from( on ) ]` /// #[ derive( Debug, Default ) ] @@ -661,7 +661,7 @@ impl FieldAttributes /// Attribute to hold parameters of forming for a specific field or variant. /// For example to avoid code From generation for it. /// -/// `#[ from( on, debug ) ]` +/// `#[ from( on ) ]` /// #[ derive( Debug, Default ) ] @@ -692,7 +692,7 @@ impl AttributeComponent for FieldAttributeConfig { return Ok( Default::default() ) }, - _ => return_syn_err!( attr, "Expects an attribute of format `#[ from( on, debug ) ]`. \nGot: {}", qt!{ #attr } ), + _ => return_syn_err!( attr, "Expects an attribute of format `#[ from( on ) ]`. \nGot: {}", qt!{ #attr } ), } } @@ -750,7 +750,7 @@ impl syn::parse::Parse for FieldAttributeConfig syn_err! ( ident, - r#"Expects an attribute of format '#[ from( on, hint ) ]' + r#"Expects an attribute of format '#[ from( on ) ]' {known} But got: '{}' "#, diff --git a/module/core/former/Readme.md b/module/core/former/Readme.md index 547f9575a3..52082b5f07 100644 --- a/module/core/former/Readme.md +++ b/module/core/former/Readme.md @@ -540,7 +540,7 @@ But it's also possible to completely override setter and write its own from scra pub struct StructWithCustomSetters { // Use `debug` to gennerate sketch of setter. - #[ scalar( setter = false, hint ) ] + #[ scalar( setter = false ) ] word : String, } @@ -813,7 +813,7 @@ The `child` function within `ParentFormer` is a custom subform setter that plays pub struct Parent { // Use `debug` to gennerate sketch of setter. - #[ scalar( setter = false, hint ) ] + #[ scalar( setter = false ) ] children : HashMap< String, Child >, } @@ -907,7 +907,7 @@ their own formers, allowing for detailed configuration within a nested builder p { // The `subform_scalar` attribute is used to specify that the 'child' field has its own former // and can be individually configured via a subform setter. This is not a collection but a single scalar entity. - #[ subform_scalar( setter = false, hint ) ] + #[ subform_scalar( setter = false ) ] child : Child, } @@ -975,7 +975,7 @@ The `child` function within `ParentFormer` is a custom subform setter that plays pub struct Parent { // Use `debug` to gennerate sketch of setter. - #[ scalar( setter = false, hint ) ] + #[ scalar( setter = false ) ] children : HashMap< String, Child >, } @@ -1056,7 +1056,7 @@ The `child` function within `ParentFormer` is a custom subform setter that plays pub struct Parent { // Use `debug` to gennerate sketch of setter. - #[ subform_entry( setter = false, hint ) ] + #[ subform_entry( setter = false ) ] child : HashMap< String, Child >, } diff --git a/module/core/former/examples/former_custom_scalar_setter.rs b/module/core/former/examples/former_custom_scalar_setter.rs index 002ecd27a1..753adcc618 100644 --- a/module/core/former/examples/former_custom_scalar_setter.rs +++ b/module/core/former/examples/former_custom_scalar_setter.rs @@ -48,7 +48,7 @@ fn main() pub struct Parent { // Use `debug` to gennerate sketch of setter. - #[ scalar( setter = false, hint ) ] + #[ scalar( setter = false ) ] children : HashMap< String, Child >, } diff --git a/module/core/former/examples/former_custom_setter_overriden.rs b/module/core/former/examples/former_custom_setter_overriden.rs index a09f2eb3e5..7c57e5eaa1 100644 --- a/module/core/former/examples/former_custom_setter_overriden.rs +++ b/module/core/former/examples/former_custom_setter_overriden.rs @@ -19,7 +19,7 @@ fn main() pub struct StructWithCustomSetters { // Use `debug` to gennerate sketch of setter. - #[ scalar( setter = false, hint ) ] + #[ scalar( setter = false ) ] word : String, } diff --git a/module/core/former/examples/former_custom_subform_collection.rs b/module/core/former/examples/former_custom_subform_collection.rs index eff4d1580e..f0de7350a0 100644 --- a/module/core/former/examples/former_custom_subform_collection.rs +++ b/module/core/former/examples/former_custom_subform_collection.rs @@ -48,7 +48,7 @@ fn main() pub struct Parent { // Use `debug` to gennerate sketch of setter. - #[ subform_collection( setter = false, hint ) ] + #[ subform_collection( setter = false ) ] children : HashMap< String, Child >, } diff --git a/module/core/former/examples/former_custom_subform_entry.rs b/module/core/former/examples/former_custom_subform_entry.rs index 8789253101..e046434da8 100644 --- a/module/core/former/examples/former_custom_subform_entry.rs +++ b/module/core/former/examples/former_custom_subform_entry.rs @@ -48,7 +48,7 @@ fn main() pub struct Parent { // Use `debug` to gennerate sketch of setter. - #[ subform_entry( setter = false, hint ) ] + #[ subform_entry( setter = false ) ] child : HashMap< String, Child >, } diff --git a/module/core/former/examples/former_custom_subform_entry2.rs b/module/core/former/examples/former_custom_subform_entry2.rs index db0c8bd836..c4592ee34f 100644 --- a/module/core/former/examples/former_custom_subform_entry2.rs +++ b/module/core/former/examples/former_custom_subform_entry2.rs @@ -48,7 +48,7 @@ fn main() pub struct Parent { // Use `debug` to gennerate sketch of setter. - #[ subform_entry( setter = false, hint ) ] + #[ subform_entry( setter = false ) ] child : HashMap< String, Child >, } diff --git a/module/core/former/examples/former_custom_subform_scalar.rs b/module/core/former/examples/former_custom_subform_scalar.rs index 219ef3fa2f..7bb0eb97cd 100644 --- a/module/core/former/examples/former_custom_subform_scalar.rs +++ b/module/core/former/examples/former_custom_subform_scalar.rs @@ -53,7 +53,7 @@ fn main() { // The `subform_scalar` attribute is used to specify that the 'child' field has its own former // and can be individually configured via a subform setter. This is not a collection but a single scalar entity. - #[ subform_scalar( setter = false, hint ) ] + #[ subform_scalar( setter = false ) ] child : Child, } diff --git a/module/core/former_meta/src/derive_former.rs b/module/core/former_meta/src/derive_former.rs index 3cde2ae40f..b6b67c33fc 100644 --- a/module/core/former_meta/src/derive_former.rs +++ b/module/core/former_meta/src/derive_former.rs @@ -70,9 +70,9 @@ pub fn mutator } }; - if mutator.hint.into() + if mutator.debug.into() { - let hint = format! + let debug = format! ( r#" = Example of custom mutator @@ -93,13 +93,13 @@ where format!( "{}", qt!{ #former_definition_types_generics_ty } ), format!( "{}", qt!{ #former_definition_types_generics_where } ), ); - // println!( "{hint}" ); + // println!( "{debug}" ); let about = format! ( r#"derive : Former item : {stru}"#, ); - diag::report_print( about, original_input, hint ); + diag::report_print( about, original_input, debug ); }; Ok( former_mutator_code ) diff --git a/module/core/former_meta/src/derive_former/field.rs b/module/core/former_meta/src/derive_former/field.rs index 0956e5cffa..67cbb68930 100644 --- a/module/core/former_meta/src/derive_former/field.rs +++ b/module/core/former_meta/src/derive_former/field.rs @@ -456,9 +456,9 @@ scalar_setter_required let setter_name = self.scalar_setter_name(); let attr = self.attrs.scalar.as_ref(); - if attr.is_some() && attr.unwrap().hint.into() + if attr.is_some() && attr.unwrap().debug.into() { - let hint = format! + let debug = format! ( r#" impl< Definition > {former}< Definition > @@ -484,7 +484,7 @@ r#"derive : Former item : {stru} field : {field_ident}"#, ); - diag::report_print( about, original_input, hint ); + diag::report_print( about, original_input, debug ); } if !self.scalar_setter_required() @@ -682,9 +682,9 @@ field : {field_ident}"#, qt!{} }; - if attr.hint.into() + if attr.debug.into() { - let hint = format! + let debug = format! ( r#" /// The collection setter provides a collection setter that returns a CollectionFormer tailored for managing a collection of child entities. It employs a generic collection definition to facilitate operations on the entire collection, such as adding or updating elements. @@ -715,7 +715,7 @@ r#"derive : Former item : {stru} field : {field_ident}"#, ); - diag::report_print( about, original_input, hint ); + diag::report_print( about, original_input, debug ); } let setters_code = qt! @@ -975,9 +975,9 @@ allowing for dynamic and flexible construction of the `{stru}` entity's {field_i setters_code }; - if attr.hint.into() + if attr.debug.into() { - let hint = format! + let debug = format! ( r#" /// Initializes and configures a subformer for adding named child entities. This method leverages an internal function @@ -1006,7 +1006,7 @@ r#"derive : Former item : {stru} field : {field_ident}"#, ); - diag::report_print( about, original_input, hint ); + diag::report_print( about, original_input, debug ); } let doc = format! @@ -1285,9 +1285,9 @@ former and end action types, ensuring a seamless developer experience when formi setters_code }; - if attr.hint.into() + if attr.debug.into() { - let hint = format! + let debug = format! ( r#" /// Extends `{former}` to include a method that initializes and configures a subformer for the '{field_ident}' field. @@ -1312,7 +1312,7 @@ r#"derive : Former item : {stru} field : {field_ident}"#, ); - diag::report_print( about, original_input, hint ); + diag::report_print( about, original_input, debug ); } let doc = format! diff --git a/module/core/former_meta/src/derive_former/field_attrs.rs b/module/core/former_meta/src/derive_former/field_attrs.rs index 8541f6fe72..f926833647 100644 --- a/module/core/former_meta/src/derive_former/field_attrs.rs +++ b/module/core/former_meta/src/derive_former/field_attrs.rs @@ -7,7 +7,6 @@ use macro_tools:: Result, AttributeComponent, AttributePropertyComponent, - AttributePropertyBoolean, AttributePropertyOptionalBoolean, AttributePropertyOptionalSyn, AttributePropertySingletone, @@ -236,7 +235,7 @@ pub struct AttributeScalarSetter pub setter : AttributePropertySetter, /// Specifies whether to provide a sketch of the subform setter as a hint. /// Defaults to `false`, which means no hint is provided unless explicitly requested. - pub hint : AttributePropertyDebug, + pub debug : AttributePropertyDebug, } impl AttributeScalarSetter @@ -314,7 +313,7 @@ where #[ inline( always ) ] fn assign( &mut self, component : IntoT ) { - self.hint = component.into(); + self.debug = component.into(); } } @@ -337,7 +336,7 @@ impl syn::parse::Parse for AttributeScalarSetter syn_err! ( ident, - r#"Expects an attribute of format '#[ scalar( name = myName, setter = true, hint ) ]' + r#"Expects an attribute of format '#[ scalar( name = myName, setter = true ) ]' {known} But got: '{}' "#, @@ -397,7 +396,7 @@ pub struct AttributeSubformScalarSetter pub setter : AttributePropertySetter, /// Specifies whether to provide a sketch of the subform setter as a hint. /// Defaults to `false`, which means no hint is provided unless explicitly requested. - pub hint : AttributePropertyDebug, + pub debug : AttributePropertyDebug, } impl AttributeSubformScalarSetter @@ -474,7 +473,7 @@ where #[ inline( always ) ] fn assign( &mut self, component : IntoT ) { - self.hint = component.into(); + self.debug = component.into(); } } @@ -497,7 +496,7 @@ impl syn::parse::Parse for AttributeSubformScalarSetter syn_err! ( ident, - r#"Expects an attribute of format '#[ subform_scalar( name = myName, setter = true, hint ) ]' + r#"Expects an attribute of format '#[ subform_scalar( name = myName, setter = true ) ]' {known} But got: '{}' "#, @@ -671,7 +670,7 @@ impl syn::parse::Parse for AttributeSubformCollectionSetter syn_err! ( ident, - r#"Expects an attribute of format '#[ subform_collection( name = myName, setter = true, hint, definition = MyDefinition ) ]' + r#"Expects an attribute of format '#[ subform_collection( name = myName, setter = true, debug, definition = MyDefinition ) ]' {known} But got: '{}' "#, @@ -739,7 +738,7 @@ pub struct AttributeSubformEntrySetter pub setter : AttributePropertySetter, /// Specifies whether to provide a sketch of the subform setter as a hint. /// Defaults to `false`, which means no hint is provided unless explicitly requested. - pub hint : AttributePropertyDebug, + pub debug : AttributePropertyDebug, } impl AttributeSubformEntrySetter @@ -816,7 +815,7 @@ where #[ inline( always ) ] fn assign( &mut self, component : IntoT ) { - self.hint = component.into(); + self.debug = component.into(); } } diff --git a/module/core/former_meta/src/derive_former/struct_attrs.rs b/module/core/former_meta/src/derive_former/struct_attrs.rs index 646a048bb7..2d6d2997c3 100644 --- a/module/core/former_meta/src/derive_former/struct_attrs.rs +++ b/module/core/former_meta/src/derive_former/struct_attrs.rs @@ -266,7 +266,7 @@ impl AttributeComponent for AttributeMutator { return Ok( Default::default() ) }, - _ => return_syn_err!( attr, "Expects an attribute of format `#[ mutator( custom = true, debug ) ]`. \nGot: {}", qt!{ #attr } ), + _ => return_syn_err!( attr, "Expects an attribute of format `#[ mutator( custom = true ) ]`. \nGot: {}", qt!{ #attr } ), } } @@ -290,7 +290,7 @@ where #[ inline( always ) ] fn assign( &mut self, component : IntoT ) { - self.hint = component.into(); + self.debug = component.into(); } } @@ -323,7 +323,8 @@ impl syn::parse::Parse for AttributeMutator syn_err! ( ident, - r#"Expects an attribute of format '#[ mutator( custom = false, hint ) ]' + // xxx + r#"Expects an attribute of format '#[ mutator( custom = false ) ]' {known} But got: '{}' "#, diff --git a/module/core/macro_tools/Readme.md b/module/core/macro_tools/Readme.md index 1102ecf09c..3c9d343d34 100644 --- a/module/core/macro_tools/Readme.md +++ b/module/core/macro_tools/Readme.md @@ -160,7 +160,7 @@ fn main() /// ## Example of code /// /// ```ignore - /// #[ mutator( custom = true, debug ) ] + /// #[ mutator( custom = true ) ] /// ``` #[ derive( Debug, Default ) ] pub struct AttributeMutator @@ -170,7 +170,7 @@ fn main() pub custom : AttributePropertyCustom, /// Specifies whether to provide a sketch of the mutator as a hint. /// Defaults to `false`, which means no hint is provided unless explicitly requested. - pub hint : AttributePropertyDebug, + pub debug : AttributePropertyDebug, } impl AttributeComponent for AttributeMutator @@ -193,7 +193,7 @@ fn main() _ => return_syn_err! ( attr, - "Expects an attribute of format `#[ mutator( custom = true, debug ) ]`. \nGot: {}", + "Expects an attribute of format `#[ mutator( custom = true ) ]`. \nGot: {}", qt! { #attr } ), } @@ -220,7 +220,7 @@ fn main() #[ inline( always ) ] fn assign( & mut self, component : IntoT ) { - self.hint = component.into(); + self.debug = component.into(); } } @@ -254,7 +254,7 @@ fn main() syn_err! ( ident, - r#"Expects an attribute of format '#[ mutator( custom = false, hint ) ]' + r#"Expects an attribute of format '#[ mutator( custom = false ) ]' {known} But got: '{}' "#, @@ -327,7 +327,7 @@ fn main() // == Test code // Parse an attribute and construct a `ItemAttributes` instance. - let input : syn::Attribute = syn::parse_quote!( #[ mutator( custom = true, hint ) ] ); + let input : syn::Attribute = syn::parse_quote!( #[ mutator( custom = true ) ] ); let attrs : ItemAttributes = ItemAttributes::from_attrs( std::iter::once( & input ) ).unwrap(); println!( "{:?}", attrs ); diff --git a/module/core/macro_tools/examples/macro_tools_attr_prop.rs b/module/core/macro_tools/examples/macro_tools_attr_prop.rs index 6e1dd5ee7a..566e19b20f 100644 --- a/module/core/macro_tools/examples/macro_tools_attr_prop.rs +++ b/module/core/macro_tools/examples/macro_tools_attr_prop.rs @@ -139,7 +139,7 @@ fn main() _ => return_syn_err! ( attr, - "Expects an attribute of format `#[ mutator( custom = true, debug ) ]`. \nGot: {}", + "Expects an attribute of format `#[ mutator( custom = true ) ]`. \nGot: {}", // xxx : just custom qt! { #attr } ), @@ -167,7 +167,7 @@ fn main() #[ inline( always ) ] fn assign( & mut self, component : IntoT ) { - self.hint = component.into(); + self.debug = component.into(); } } @@ -201,7 +201,7 @@ fn main() syn_err! ( ident, - r#"Expects an attribute of format '#[ mutator( custom = false, hint ) ]' + r#"Expects an attribute of format '#[ mutator( custom = false ) ]' {known} But got: '{}' "#, @@ -274,7 +274,7 @@ fn main() // == test code // Parse an attribute and construct a `ItemAttributes` instance. - let input : syn::Attribute = syn::parse_quote!( #[ mutator( custom = true, hint ) ] ); + let input : syn::Attribute = syn::parse_quote!( #[ mutator( custom = true ) ] ); let attrs : ItemAttributes = ItemAttributes::from_attrs( std::iter::once( & input ) ).unwrap(); println!( "{:?}", attrs ); diff --git a/module/core/macro_tools/src/attr_prop.rs b/module/core/macro_tools/src/attr_prop.rs index 37fb31ca60..cb515c4217 100644 --- a/module/core/macro_tools/src/attr_prop.rs +++ b/module/core/macro_tools/src/attr_prop.rs @@ -70,7 +70,7 @@ //! } //! } //! -//! let input : syn::Attribute = syn::parse_quote!( #[ attribute( enabled = true, debug = false ) ] ); +//! let input : syn::Attribute = syn::parse_quote!( #[ attribute( enabled = true ) ] ); //! let meta = match input.meta //! { //! syn::Meta::List( meta_list ) => meta_list, diff --git a/module/core/macro_tools/src/attr_prop/boolean.rs b/module/core/macro_tools/src/attr_prop/boolean.rs index 9a884b548e..37c54fc0f0 100644 --- a/module/core/macro_tools/src/attr_prop/boolean.rs +++ b/module/core/macro_tools/src/attr_prop/boolean.rs @@ -77,7 +77,7 @@ use crate::*; /// } /// } /// -/// let input : syn::Attribute = syn::parse_quote!( #[ attribute( enabled = true, debug = false ) ] ); +/// let input : syn::Attribute = syn::parse_quote!( #[ attribute( enabled = true ) ] ); /// let meta = match input.meta /// { /// syn::Meta::List( meta_list ) => meta_list, diff --git a/module/core/macro_tools/tests/inc/attr_prop_test.rs b/module/core/macro_tools/tests/inc/attr_prop_test.rs index 67acaf75a8..223f8be5d4 100644 --- a/module/core/macro_tools/tests/inc/attr_prop_test.rs +++ b/module/core/macro_tools/tests/inc/attr_prop_test.rs @@ -69,7 +69,7 @@ fn attr_prop_test() } } - let input : syn::Attribute = syn::parse_quote!( #[ attribute( enabled = true, debug = false ) ] ); + let input : syn::Attribute = syn::parse_quote!( #[ attribute( enabled = true ) ] ); let meta = match input.meta { syn::Meta::List( meta_list ) => meta_list, @@ -87,7 +87,7 @@ fn attr_prop_test() let attr : AttributePropertyBoolean< DebugMarker > = false.into(); assert_eq!( attr.internal(), false ); - let input : syn::Attribute = syn::parse_quote!( #[ attribute( enabled = true, debug = false ) ] ); + let input : syn::Attribute = syn::parse_quote!( #[ attribute( enabled = true ) ] ); let meta = match input.meta { syn::Meta::List( meta_list ) => meta_list, diff --git a/module/move/wca/src/ca/facade.rs b/module/move/wca/src/ca/facade.rs index a5a466cba6..cdc9edb599 100644 --- a/module/move/wca/src/ca/facade.rs +++ b/module/move/wca/src/ca/facade.rs @@ -65,7 +65,7 @@ pub( crate ) mod private /// The name of the property. pub name : &'a str, /// The hint for the property. - pub hint : &'a str, + pub debug : &'a str, /// The tag representing the property's type. pub tag : Type, } diff --git a/module/move/wca/src/ca/grammar/command.rs b/module/move/wca/src/ca/grammar/command.rs index a582aeee91..08bf6babdd 100644 --- a/module/move/wca/src/ca/grammar/command.rs +++ b/module/move/wca/src/ca/grammar/command.rs @@ -23,7 +23,7 @@ pub( crate ) mod private pub struct ValueDescription { /// providing guidance to the user for entering a valid value - pub hint : String, + pub debug : String, /// expected type of a value pub kind : Type, /// subject optional parameter @@ -90,7 +90,7 @@ pub( crate ) mod private pub struct Command { /// Command common hint. - pub hint : String, + pub debug : String, /// Command full hint. pub long_hint : String, /// Phrase descriptor for command. From 0b9968c19ebd858372739d156b265ace40572d52 Mon Sep 17 00:00:00 2001 From: wandalen Date: Wed, 29 May 2024 00:33:19 +0300 Subject: [PATCH 19/59] former : property hint - --- module/core/macro_tools/examples/macro_tools_attr_prop.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/module/core/macro_tools/examples/macro_tools_attr_prop.rs b/module/core/macro_tools/examples/macro_tools_attr_prop.rs index 566e19b20f..97c2489a61 100644 --- a/module/core/macro_tools/examples/macro_tools_attr_prop.rs +++ b/module/core/macro_tools/examples/macro_tools_attr_prop.rs @@ -42,6 +42,7 @@ fn main() AttributeComponent, AttributePropertyComponent, AttributePropertyBoolean, + AttributePropertySingletone, }; use former_types::ComponentAssign; From b095bb3c4ec868664352dc53aa445c0707677c75 Mon Sep 17 00:00:00 2001 From: wandalen Date: Wed, 29 May 2024 00:45:34 +0300 Subject: [PATCH 20/59] macro_tools : cleaning --- debug | 3 +++ ...m_inner_variants_duplicates_some_off_default_off.rs | 5 +++-- module/core/derive_tools_meta/src/derive/from.rs | 8 ++------ module/core/macro_tools/Readme.md | 10 ++++++---- .../core/macro_tools/examples/macro_tools_attr_prop.rs | 1 - 5 files changed, 14 insertions(+), 13 deletions(-) diff --git a/debug b/debug index e69de29bb2..c233ba713f 100644 --- a/debug +++ b/debug @@ -0,0 +1,3 @@ +[program_tools_v1 0b9968c19] former : property hint - + 1 file changed, 1 insertion(+) +Already up to date. diff --git a/module/core/derive_tools/tests/inc/from_inner_variants_duplicates_some_off_default_off.rs b/module/core/derive_tools/tests/inc/from_inner_variants_duplicates_some_off_default_off.rs index 8148a66320..6445f17e8e 100644 --- a/module/core/derive_tools/tests/inc/from_inner_variants_duplicates_some_off_default_off.rs +++ b/module/core/derive_tools/tests/inc/from_inner_variants_duplicates_some_off_default_off.rs @@ -11,8 +11,9 @@ pub enum GetData Nothing2, FromString( String ), // #[ from( on ) ] - #[ from( on, debug) ] - // xxx : rename `hint` to `debug` and rid rid `off = true` + #[ from( on ) ] + // #[ from( debug ) ] + // xxx : should that work? FromString2( String ), FromPair( String, String ), #[ from( on ) ] diff --git a/module/core/derive_tools_meta/src/derive/from.rs b/module/core/derive_tools_meta/src/derive/from.rs index 471109b114..818d20c40c 100644 --- a/module/core/derive_tools_meta/src/derive/from.rs +++ b/module/core/derive_tools_meta/src/derive/from.rs @@ -14,8 +14,6 @@ use macro_tools:: use former_types::ComponentAssign; -// xxx2 : get complete From for enums - // pub fn from( input : proc_macro::TokenStream ) -> Result< proc_macro2::TokenStream > @@ -56,7 +54,7 @@ pub fn from( input : proc_macro::TokenStream ) -> Result< proc_macro2::TokenStre &generics_impl, &generics_ty, &generics_where, - field_names.next().unwrap(), // xxx : ? + field_names.next().unwrap(), &field_types.next().unwrap(), ), ( 1, None ) => @@ -413,8 +411,6 @@ fn generate_unit } } -// xxx2 : get completed - // == item attributes /// @@ -673,7 +669,7 @@ pub struct FieldAttributeConfig /// Specifies whether to print a sketch of generated `From` or not. /// Defaults to `false`, which means no code is printed unless explicitly requested. pub debug : AttributePropertyDebug, - // qqq : xxx : implement + // qqq : apply debug properties to all brenches, not only enums } impl AttributeComponent for FieldAttributeConfig diff --git a/module/core/macro_tools/Readme.md b/module/core/macro_tools/Readme.md index 3c9d343d34..b45e890e93 100644 --- a/module/core/macro_tools/Readme.md +++ b/module/core/macro_tools/Readme.md @@ -96,6 +96,7 @@ fn main() AttributeComponent, AttributePropertyComponent, AttributePropertyBoolean, + AttributePropertySingletone, }; use former_types::ComponentAssign; @@ -160,7 +161,7 @@ fn main() /// ## Example of code /// /// ```ignore - /// #[ mutator( custom = true ) ] + /// #[ mutator( custom = true, debug = true ) ] /// ``` #[ derive( Debug, Default ) ] pub struct AttributeMutator @@ -168,7 +169,7 @@ fn main() /// Indicates whether a custom mutator should be generated. /// Defaults to `false`, meaning no custom mutator is generated unless explicitly requested. pub custom : AttributePropertyCustom, - /// Specifies whether to provide a sketch of the mutator as a hint. + /// Specifies whether to print code generated for the field. /// Defaults to `false`, which means no hint is provided unless explicitly requested. pub debug : AttributePropertyDebug, } @@ -301,7 +302,7 @@ fn main() impl AttributePropertyComponent for AttributePropertyDebugMarker { - const KEYWORD : & 'static str = "hint"; + const KEYWORD : & 'static str = "debug"; } /// Specifies whether to provide a sketch as a hint. @@ -324,7 +325,7 @@ fn main() /// Defaults to `false`, meaning no custom code is generated unless explicitly requested. pub type AttributePropertyCustom = AttributePropertyBoolean< AttributePropertyCustomMarker >; - // == Test code + // == test code // Parse an attribute and construct a `ItemAttributes` instance. let input : syn::Attribute = syn::parse_quote!( #[ mutator( custom = true ) ] ); @@ -340,6 +341,7 @@ fn main() assert_eq!( attr.internal(), false ); } + ``` Try out `cargo run --example macro_tools_attr_prop`. diff --git a/module/core/macro_tools/examples/macro_tools_attr_prop.rs b/module/core/macro_tools/examples/macro_tools_attr_prop.rs index 97c2489a61..8b4a6639e4 100644 --- a/module/core/macro_tools/examples/macro_tools_attr_prop.rs +++ b/module/core/macro_tools/examples/macro_tools_attr_prop.rs @@ -141,7 +141,6 @@ fn main() ( attr, "Expects an attribute of format `#[ mutator( custom = true ) ]`. \nGot: {}", - // xxx : just custom qt! { #attr } ), } From 2765144911fcae19f068e985d20d172bd28cc203 Mon Sep 17 00:00:00 2001 From: wandalen Date: Wed, 29 May 2024 00:48:31 +0300 Subject: [PATCH 21/59] former : shorter property custom --- module/core/former/Readme.md | 2 +- module/core/former/examples/former_custom_mutator.rs | 2 +- .../former_tests/attribute_storage_with_mutator.rs | 2 +- .../former_meta/src/derive_former/struct_attrs.rs | 11 +++++------ 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/module/core/former/Readme.md b/module/core/former/Readme.md index 52082b5f07..68c270f3b8 100644 --- a/module/core/former/Readme.md +++ b/module/core/former/Readme.md @@ -1195,7 +1195,7 @@ held within the storage. #[ derive( Debug, PartialEq, Former ) ] #[ storage_fields( a : i32, b : Option< String > ) ] - #[ mutator( custom = true ) ] + #[ mutator( custom ) ] pub struct Struct1 { c : String, diff --git a/module/core/former/examples/former_custom_mutator.rs b/module/core/former/examples/former_custom_mutator.rs index 5d83fe77c9..e70323e588 100644 --- a/module/core/former/examples/former_custom_mutator.rs +++ b/module/core/former/examples/former_custom_mutator.rs @@ -41,7 +41,7 @@ fn main() #[ derive( Debug, PartialEq, Former ) ] #[ storage_fields( a : i32, b : Option< String > ) ] - #[ mutator( custom = true ) ] + #[ mutator( custom ) ] pub struct Struct1 { c : String, diff --git a/module/core/former/tests/inc/former_tests/attribute_storage_with_mutator.rs b/module/core/former/tests/inc/former_tests/attribute_storage_with_mutator.rs index 57936294d3..983fbc655e 100644 --- a/module/core/former/tests/inc/former_tests/attribute_storage_with_mutator.rs +++ b/module/core/former/tests/inc/former_tests/attribute_storage_with_mutator.rs @@ -3,7 +3,7 @@ use super::*; #[ derive( Debug, PartialEq, the_module::Former ) ] #[ storage_fields( a : i32, b : Option< String > ) ] -#[ mutator( custom = true ) ] +#[ mutator( custom ) ] // #[ debug ] // #[ derive( Debug, PartialEq ) ] pub struct Struct1 diff --git a/module/core/former_meta/src/derive_former/struct_attrs.rs b/module/core/former_meta/src/derive_former/struct_attrs.rs index 2d6d2997c3..d8177e4507 100644 --- a/module/core/former_meta/src/derive_former/struct_attrs.rs +++ b/module/core/former_meta/src/derive_former/struct_attrs.rs @@ -10,7 +10,6 @@ use macro_tools:: Result, AttributeComponent, AttributePropertyComponent, - AttributePropertyBoolean, AttributePropertySingletone, }; @@ -233,7 +232,7 @@ impl syn::parse::Parse for AttributeStorageFields /// /// ## Example of code /// ```ignore -/// custom = true, debug +/// custom, debug /// ``` // xxx @@ -266,7 +265,7 @@ impl AttributeComponent for AttributeMutator { return Ok( Default::default() ) }, - _ => return_syn_err!( attr, "Expects an attribute of format `#[ mutator( custom = true ) ]`. \nGot: {}", qt!{ #attr } ), + _ => return_syn_err!( attr, "Expects an attribute of format `#[ mutator( custom ) ]`. \nGot: {}", qt!{ #attr } ), } } @@ -324,7 +323,7 @@ impl syn::parse::Parse for AttributeMutator ( ident, // xxx - r#"Expects an attribute of format '#[ mutator( custom = false ) ]' + r#"Expects an attribute of format '#[ mutator( custom ) ]' {known} But got: '{}' "#, @@ -340,7 +339,7 @@ impl syn::parse::Parse for AttributeMutator let ident : syn::Ident = input.parse()?; match ident.to_string().as_str() { - AttributePropertyCustom::KEYWORD => result.assign( AttributePropertyCustom::parse( input )? ), + AttributePropertyCustom::KEYWORD => result.assign( AttributePropertyCustom::from( true ) ), AttributePropertyDebug::KEYWORD => result.assign( AttributePropertyDebug::from( true ) ), _ => return Err( error( &ident ) ), } @@ -445,4 +444,4 @@ impl AttributePropertyComponent for AttributePropertyCustomMarker /// Indicates whether a custom code should be generated. /// Defaults to `false`, meaning no custom code is generated unless explicitly requested. -pub type AttributePropertyCustom = AttributePropertyBoolean< AttributePropertyCustomMarker >; +pub type AttributePropertyCustom = AttributePropertySingletone< AttributePropertyCustomMarker >; From 31cdcc00a34ca86c8cad3b880928d3063c00a387 Mon Sep 17 00:00:00 2001 From: wandalen Date: Wed, 29 May 2024 00:50:15 +0300 Subject: [PATCH 22/59] former : shorter property custom --- module/core/former_meta/src/derive_former/struct_attrs.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/module/core/former_meta/src/derive_former/struct_attrs.rs b/module/core/former_meta/src/derive_former/struct_attrs.rs index d8177e4507..3c2f1fc094 100644 --- a/module/core/former_meta/src/derive_former/struct_attrs.rs +++ b/module/core/former_meta/src/derive_former/struct_attrs.rs @@ -322,7 +322,6 @@ impl syn::parse::Parse for AttributeMutator syn_err! ( ident, - // xxx r#"Expects an attribute of format '#[ mutator( custom ) ]' {known} But got: '{}' From 25629e9d5ed46ff7cda0f0463503308a2ce35c2a Mon Sep 17 00:00:00 2001 From: wandalen Date: Wed, 29 May 2024 00:51:22 +0300 Subject: [PATCH 23/59] former : cleaning --- module/core/former_meta/src/derive_former/struct_attrs.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/module/core/former_meta/src/derive_former/struct_attrs.rs b/module/core/former_meta/src/derive_former/struct_attrs.rs index 3c2f1fc094..1c63833cdb 100644 --- a/module/core/former_meta/src/derive_former/struct_attrs.rs +++ b/module/core/former_meta/src/derive_former/struct_attrs.rs @@ -235,8 +235,6 @@ impl syn::parse::Parse for AttributeStorageFields /// custom, debug /// ``` -// xxx - #[ derive( Debug, Default ) ] pub struct AttributeMutator { @@ -246,7 +244,6 @@ pub struct AttributeMutator /// Specifies whether to provide a sketch of the mutator as a hint. /// Defaults to `false`, which means no hint is provided unless explicitly requested. pub debug : AttributePropertyDebug, - // qqq : xxx : use the property. currently it's not used } impl AttributeComponent for AttributeMutator From 6ac36ec5cb05daedc8072e6f181f93463d4fef54 Mon Sep 17 00:00:00 2001 From: wandalen Date: Wed, 29 May 2024 09:17:02 +0300 Subject: [PATCH 24/59] former : cleaning --- .../derive_tools_meta/src/derive/as_ref.rs | 1 - .../src/component/components_assign.rs | 26 ++-- module/core/former_meta/src/derive_former.rs | 89 ++++++------ .../former_meta/src/derive_former/field.rs | 128 +++++++++++------- module/core/macro_tools/src/lib.rs | 15 +- 5 files changed, 145 insertions(+), 114 deletions(-) diff --git a/module/core/derive_tools_meta/src/derive/as_ref.rs b/module/core/derive_tools_meta/src/derive/as_ref.rs index bf5676839d..dba4eacacf 100644 --- a/module/core/derive_tools_meta/src/derive/as_ref.rs +++ b/module/core/derive_tools_meta/src/derive/as_ref.rs @@ -9,7 +9,6 @@ pub fn as_ref( input : proc_macro::TokenStream ) -> Result< proc_macro2::TokenSt let original_input = input.clone(); let parsed = syn::parse::< syn::ItemStruct >( input )?; let has_debug = attr::has_debug( parsed.attrs.iter() )?; - let field_type = item_struct::first_field_type( &parsed )?; let item_name = &parsed.ident; diff --git a/module/core/former_meta/src/component/components_assign.rs b/module/core/former_meta/src/component/components_assign.rs index 4a69425dd3..9e6b3fdd6c 100644 --- a/module/core/former_meta/src/component/components_assign.rs +++ b/module/core/former_meta/src/component/components_assign.rs @@ -1,6 +1,6 @@ use super::*; -use macro_tools::{ attr, diag, Result }; -use iter_tools::{ Itertools, process_results }; +use macro_tools::{ attr, diag, Result, format_ident }; +use iter_tools::{ Itertools }; /// /// Generate `ComponentsAssign` trait implementation for the type, providing `components_assign` function @@ -17,13 +17,19 @@ pub fn components_assign( input : proc_macro::TokenStream ) -> Result< proc_macr // name let item_name = &parsed.ident; - let trait_name = format!( "{}ComponentsAssign", item_name ); - let trait_ident = syn::Ident::new( &trait_name, item_name.span() ); - let method_name = format!( "{}_assign", item_name.to_string().to_case( Case::Snake ) ); - let method_ident = syn::Ident::new( &method_name, item_name.span() ); - // xxx : use macro ident_format!() + let trait_ident = format_ident! + { + "{}ComponentsAssign", + item_name + }; + let method_ident = format_ident! + { + "{}_assign", + item_name.to_string().to_case( Case::Snake ) + }; // fields +// fields let ( bounds1, bounds2, component_assigns ) : ( Vec< _ >, Vec< _ >, Vec< _ > ) = parsed.fields.iter().map( | field | { let field_type = &field.ty; @@ -33,9 +39,9 @@ pub fn components_assign( input : proc_macro::TokenStream ) -> Result< proc_macr ( bound1, bound2, component_assign ) }).multiunzip(); - let bounds1 : Vec< _ > = process_results( bounds1, | iter | iter.collect() )?; - let bounds2 : Vec< _ > = process_results( bounds2, | iter | iter.collect() )?; - let component_assigns : Vec< _ > = process_results( component_assigns, | iter | iter.collect() )?; + let bounds1 : Vec< _ > = bounds1.into_iter().collect::< Result< _ > >()?; + let bounds2 : Vec< _ > = bounds2.into_iter().collect::< Result< _ > >()?; + let component_assigns : Vec< _ > = component_assigns.into_iter().collect::< Result< _ > >()?; // code let doc = format!( "Interface to assign instance from set of components exposed by a single argument." ); diff --git a/module/core/former_meta/src/derive_former.rs b/module/core/former_meta/src/derive_former.rs index b6b67c33fc..ac2be6c48f 100644 --- a/module/core/former_meta/src/derive_former.rs +++ b/module/core/former_meta/src/derive_former.rs @@ -1,6 +1,6 @@ use super::*; -use iter_tools::{ Itertools, process_results }; +use iter_tools::{ Itertools }; use macro_tools::{ attr, diag, generic_params, generic_args, typ, derive, Result }; use proc_macro2::TokenStream; @@ -43,7 +43,7 @@ use struct_attrs::*; pub fn mutator ( - stru : &syn::Ident, + item : &syn::Ident, original_input : &proc_macro::TokenStream, mutator : &AttributeMutator, former_definition_types : &syn::Ident, @@ -97,7 +97,7 @@ where let about = format! ( r#"derive : Former -item : {stru}"#, +item : {item}"#, ); diag::report_print( about, original_input, debug ); }; @@ -109,14 +109,14 @@ item : {stru}"#, /// Generate documentation for the former. /// -fn doc_generate( stru : &syn::Ident ) -> ( String, String ) +fn doc_generate( item : &syn::Ident ) -> ( String, String ) { let doc_former_mod = format! ( r#" Implementation of former for [{}]. "#, - stru + item ); let doc_former_struct = format! @@ -127,7 +127,7 @@ Structure to form [{}]. Represents a forming entity designed to construct object This structure holds temporary storage and context during the formation process and utilizes a defined end strategy to finalize the object creation. "#, - stru + item ); ( doc_former_mod, doc_former_struct ) @@ -155,24 +155,18 @@ pub fn former( input : proc_macro::TokenStream ) -> Result< TokenStream > /* names */ let vis = &ast.vis; - let stru = &ast.ident; - let former_name = format!( "{}Former", stru ); - let former = syn::Ident::new( &former_name, stru.span() ); - let former_storage_name = format!( "{}FormerStorage", stru ); - let former_storage = syn::Ident::new( &former_storage_name, stru.span() ); - let former_definition_name = format!( "{}FormerDefinition", stru ); - let former_definition = syn::Ident::new( &former_definition_name, stru.span() ); - let former_definition_types_name = format!( "{}FormerDefinitionTypes", stru ); - let former_definition_types = syn::Ident::new( &former_definition_types_name, stru.span() ); - let as_subformer_name = format!( "{}AsSubformer", stru ); - let as_subformer = syn::Ident::new( &as_subformer_name, stru.span() ); - let as_subformer_end_name = format!( "{}AsSubformerEnd", stru ); - let as_subformer_end = syn::Ident::new( &as_subformer_end_name, stru.span() ); + let item = &ast.ident; + let former = format_ident!( "{item}Former" ); + let former_storage = format_ident!( "{item}FormerStorage" ); + let former_definition = format_ident!( "{item}FormerDefinition" ); + let former_definition_types = format_ident!( "{item}FormerDefinitionTypes" ); + let as_subformer = format_ident!( "{item}AsSubformer" ); + let as_subformer_end = format_ident!( "{item}AsSubformerEnd" ); let as_subformer_end_doc = format! ( r#" -Represents an end condition for former of [`${stru}`], tying the lifecycle of forming processes to a broader context. +Represents an end condition for former of [`${item}`], tying the lifecycle of forming processes to a broader context. This trait is intended for use with subformer alias, ensuring that end conditions are met according to the specific needs of the broader forming context. It mandates the implementation of `former::FormingEnd`. @@ -189,7 +183,7 @@ specific needs of the broader forming context. It mandates the implementation of let extra : macro_tools::syn::AngleBracketedGenericArguments = parse_quote! { - < (), #stru < #struct_generics_ty >, former::ReturnPreformed > + < (), #item < #struct_generics_ty >, former::ReturnPreformed > }; let former_definition_args = generic_args::merge( &generics.into_generic_args(), &extra.into() ).args; @@ -216,12 +210,12 @@ specific needs of the broader forming context. It mandates the implementation of Definition : former::FormerDefinition < Storage = #former_storage < #struct_generics_ty >, - Formed = #stru < #struct_generics_ty >, + Formed = #item < #struct_generics_ty >, >, Definition::Types : former::FormerDefinitionTypes < Storage = #former_storage < #struct_generics_ty >, - Formed = #stru < #struct_generics_ty >, + Formed = #item < #struct_generics_ty >, >, }; let extra = generic_params::merge( &generics, &extra.into() ); @@ -233,7 +227,7 @@ specific needs of the broader forming context. It mandates the implementation of let extra : macro_tools::GenericsWithWhere = parse_quote! { - < __Context = (), __Formed = #stru < #struct_generics_ty > > + < __Context = (), __Formed = #item < #struct_generics_ty > > }; let former_definition_types_generics = generic_params::merge( &generics, &extra.into() ); let ( former_definition_types_generics_with_defaults, former_definition_types_generics_impl, former_definition_types_generics_ty, former_definition_types_generics_where ) @@ -245,7 +239,7 @@ specific needs of the broader forming context. It mandates the implementation of let extra : macro_tools::GenericsWithWhere = parse_quote! { - < __Context = (), __Formed = #stru < #struct_generics_ty >, __End = former::ReturnPreformed > + < __Context = (), __Formed = #item < #struct_generics_ty >, __End = former::ReturnPreformed > }; let generics_of_definition = generic_params::merge( &generics, &extra.into() ); let ( former_definition_generics_with_defaults, former_definition_generics_impl, former_definition_generics_ty, former_definition_generics_where ) @@ -255,31 +249,29 @@ specific needs of the broader forming context. It mandates the implementation of /* struct attributes */ - let ( _doc_former_mod, doc_former_struct ) = doc_generate( stru ); + let ( _doc_former_mod, doc_former_struct ) = doc_generate( item ); let ( perform, perform_output, perform_generics ) = struct_attrs.performer()?; /* fields */ let fields = derive::named_fields( &ast )?; - let formed_fields : Vec< Result< FormerField< '_ > > > = fields + let formed_fields : Vec< _ > = fields .into_iter() .map( | field | { FormerField::from_syn( field, true, true ) }) - .collect(); - let formed_fields : Vec< _ > = process_results( formed_fields, | iter | iter.collect() )?; + .collect::< Result< _ > >()?; - let storage_fields : Vec< Result< FormerField< '_ > > > = struct_attrs + let storage_fields : Vec< _ > = struct_attrs .storage_fields() .iter() .map( | field | { - FormerField::from_syn( &field, true, false ) + FormerField::from_syn( field, true, false ) }) - .collect(); - let storage_fields : Vec< _ > = process_results( storage_fields, | iter | iter.collect() )?; + .collect::< Result< _ > >()?; let ( @@ -302,7 +294,7 @@ specific needs of the broader forming context. It mandates the implementation of field.storage_field_preform(), field.former_field_setter ( - &stru, + &item, &original_input, &struct_generics_impl, &struct_generics_ty, @@ -318,11 +310,14 @@ specific needs of the broader forming context. It mandates the implementation of let results : Result< Vec< _ > > = former_field_setter.into_iter().collect(); let ( former_field_setter, namespace_code ) : ( Vec< _ >, Vec< _ > ) = results?.into_iter().unzip(); - let storage_field_preform : Vec< _ > = process_results( storage_field_preform, | iter | iter.collect() )?; + // let storage_field_preform : Vec< _ > = process_results( storage_field_preform, | iter | iter.collect() )?; + let storage_field_preform : Vec< _ > = storage_field_preform + .into_iter() + .collect::< Result< _ > >()?; let former_mutator_code = mutator ( - &stru, + &item, &original_input, &struct_attrs.mutator, &former_definition_types, @@ -337,7 +332,7 @@ specific needs of the broader forming context. It mandates the implementation of // = formed #[ automatically_derived ] - impl < #struct_generics_impl > #stru < #struct_generics_ty > + impl < #struct_generics_impl > #item < #struct_generics_ty > where #struct_generics_where { @@ -357,7 +352,7 @@ specific needs of the broader forming context. It mandates the implementation of // = entity to former impl< #struct_generics_impl Definition > former::EntityToFormer< Definition > - for #stru < #struct_generics_ty > + for #item < #struct_generics_ty > where Definition : former::FormerDefinition< Storage = #former_storage < #struct_generics_ty > >, #struct_generics_where @@ -366,7 +361,7 @@ specific needs of the broader forming context. It mandates the implementation of } impl< #struct_generics_impl > former::EntityToStorage - for #stru < #struct_generics_ty > + for #item < #struct_generics_ty > where #struct_generics_where { @@ -374,7 +369,7 @@ specific needs of the broader forming context. It mandates the implementation of } impl< #struct_generics_impl __Context, __Formed, __End > former::EntityToDefinition< __Context, __Formed, __End > - for #stru < #struct_generics_ty > + for #item < #struct_generics_ty > where __End : former::FormingEnd< #former_definition_types < #struct_generics_ty __Context, __Formed > >, #struct_generics_where @@ -384,7 +379,7 @@ specific needs of the broader forming context. It mandates the implementation of } impl< #struct_generics_impl __Context, __Formed > former::EntityToDefinitionTypes< __Context, __Formed > - for #stru < #struct_generics_ty > + for #item < #struct_generics_ty > where #struct_generics_where { @@ -506,7 +501,7 @@ specific needs of the broader forming context. It mandates the implementation of where #struct_generics_where { - type Preformed = #stru < #struct_generics_ty >; + type Preformed = #item < #struct_generics_ty >; } impl < #struct_generics_impl > former::StoragePreform @@ -514,14 +509,14 @@ specific needs of the broader forming context. It mandates the implementation of where #struct_generics_where { - // type Preformed = #stru < #struct_generics_ty >; + // type Preformed = #item < #struct_generics_ty >; fn preform( mut self ) -> Self::Preformed { #( #storage_field_preform )* // Rust does not support that, yet // let result = < Definition::Types as former::FormerDefinitionTypes >::Formed - let result = #stru :: < #struct_generics_ty > + let result = #item :: < #struct_generics_ty > { #( #storage_field_name )* // #( #storage_field_name, )* @@ -660,8 +655,8 @@ specific needs of the broader forming context. It mandates the implementation of impl< #former_generics_impl > #former< #former_generics_ty > where - Definition : former::FormerDefinition< Storage = #former_storage < #struct_generics_ty >, Formed = #stru < #struct_generics_ty > >, - Definition::Types : former::FormerDefinitionTypes< Storage = #former_storage < #struct_generics_ty >, Formed = #stru < #struct_generics_ty > >, + Definition : former::FormerDefinition< Storage = #former_storage < #struct_generics_ty >, Formed = #item < #struct_generics_ty > >, + Definition::Types : former::FormerDefinitionTypes< Storage = #former_storage < #struct_generics_ty >, Formed = #item < #struct_generics_ty > >, #former_generics_where { @@ -778,7 +773,7 @@ specific needs of the broader forming context. It mandates the implementation of if has_debug { - let about = format!( "derive : Former\nstructure : {stru}" ); + let about = format!( "derive : Former\nstructure : {item}" ); diag::report_print( about, &original_input, &result ); } diff --git a/module/core/former_meta/src/derive_former/field.rs b/module/core/former_meta/src/derive_former/field.rs index 67cbb68930..c04845e31f 100644 --- a/module/core/former_meta/src/derive_former/field.rs +++ b/module/core/former_meta/src/derive_former/field.rs @@ -330,7 +330,7 @@ scalar_setter_required pub fn former_field_setter ( &self, - stru : &syn::Ident, + item : &syn::Ident, original_input : &proc_macro::TokenStream, struct_generics_impl : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, struct_generics_ty : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, @@ -348,7 +348,7 @@ scalar_setter_required let namespace_code = qt! {}; let setters_code = self.scalar_setter ( - stru, + item, former, former_storage, original_input, @@ -359,7 +359,7 @@ scalar_setter_required { let ( setters_code2, namespace_code2 ) = self.subform_scalar_setter ( - stru, + item, former, former_storage, former_generics_ty, @@ -380,7 +380,7 @@ scalar_setter_required { let ( setters_code2, namespace_code2 ) = self.subform_collection_setter ( - stru, + item, former, former_storage, former_generics_impl, @@ -400,7 +400,7 @@ scalar_setter_required { let ( setters_code2, namespace_code2 ) = self.subform_entry_setter ( - stru, + item, former, former_storage, former_generics_ty, @@ -444,7 +444,7 @@ scalar_setter_required pub fn scalar_setter ( &self, - stru : &syn::Ident, + item : &syn::Ident, former : &syn::Ident, former_storage : &syn::Ident, original_input : &proc_macro::TokenStream, @@ -481,7 +481,7 @@ where let about = format! ( r#"derive : Former -item : {stru} +item : {item} field : {field_ident}"#, ); diag::report_print( about, original_input, debug ); @@ -524,7 +524,7 @@ field : {field_ident}"#, pub fn subform_collection_setter ( &self, - stru : &syn::Ident, + item : &syn::Ident, former : &syn::Ident, former_storage : &syn::Ident, former_generics_impl : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, @@ -540,11 +540,21 @@ field : {field_ident}"#, let params = typ::type_parameters( &field_typ, .. ); use convert_case::{ Case, Casing }; - let subform_collection_end_name = format!( "{}SubformCollection{}End", stru, field_ident.to_string().to_case( Case::Pascal ) ); - let subform_collection_end = syn::Ident::new( &subform_collection_end_name, field_ident.span() ); - let subform_collection_name = format!( "_{}_subform_collection", field_ident ); - let subform_collection = syn::Ident::new( &subform_collection_name, field_ident.span() ); + // example : `ParentSubformCollectionChildrenEnd` + let subform_collection_end = format_ident! + { + "{}SubformCollection{}End", + item, + field_ident.to_string().to_case( Case::Pascal ) + }; + + // example : `_children_subform_collection` + let subform_collection = format_ident! + { + "_{}_subform_collection", + field_ident + }; // example : `former::VectorDefinition` let subformer_definition = &attr.definition; let subformer_definition = if subformer_definition.is_some() @@ -576,7 +586,7 @@ field : {field_ident}"#, ( "Collection setter for the '{}' field. Method {} unlike method {} accept custom collection subformer.", field_ident, - subform_collection_name, + subform_collection, field_ident, ); @@ -712,7 +722,7 @@ where let about = format! ( r#"derive : Former -item : {stru} +item : {item} field : {field_ident}"#, ); diag::report_print( about, original_input, debug ); @@ -730,10 +740,10 @@ field : {field_ident}"#, let subform_collection_end_doc = format! ( r#" -A callback structure to manage the final stage of forming a `{0}` for the `{stru}` collection. +A callback structure to manage the final stage of forming a `{0}` for the `{item}` collection. -This callback is used to integrate the contents of a temporary `{0}` back into the original `{stru}` former -after the subforming process is completed. It replaces the existing content of the `{field_ident}` field in `{stru}` +This callback is used to integrate the contents of a temporary `{0}` back into the original `{item}` former +after the subforming process is completed. It replaces the existing content of the `{field_ident}` field in `{item}` with the new content generated during the subforming process. "#, format!( "{}", qt!{ #field_typ } ), @@ -844,7 +854,7 @@ with the new content generated during the subforming process. pub fn subform_entry_setter ( &self, - stru : &syn::Ident, + item : &syn::Ident, former : &syn::Ident, former_storage : &syn::Ident, former_generics_ty : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, @@ -867,29 +877,36 @@ with the new content generated during the subforming process. // example : `children` let setter_name = self.subform_entry_setter_name(); - // example : `ParentSubformEntryChildrenEnd`` - let subform_entry_end_name = format!( "{}SubformEntry{}End", stru, field_ident.to_string().to_case( Case::Pascal ) ); - let subform_entry_end = syn::Ident::new( &subform_entry_end_name, field_ident.span() ); + // example : `ParentSubformEntryChildrenEnd` + let subform_entry_end = format_ident! + { + "{}SubformEntry{}End", + item, + field_ident.to_string().to_case( Case::Pascal ) + }; // example : `_children_subform_entry` - let subform_entry_name = format!( "_{}_subform_entry", field_ident ); - let subform_entry = syn::Ident::new( &subform_entry_name, field_ident.span() ); + let subform_entry = format_ident! + { + "_{}_subform_entry", + field_ident + }; let doc = format! ( r#" -Initiates the addition of {field_ident} to the `{stru}` entity using a dedicated subformer. +Initiates the addition of {field_ident} to the `{item}` entity using a dedicated subformer. This method configures and returns a subformer specialized for the `{0}` entities' formation process, -which is part of the `{stru}` entity's construction. The subformer is set up with a specific end condition +which is part of the `{item}` entity's construction. The subformer is set up with a specific end condition handled by `{subform_entry_end}`, ensuring that the {field_ident} are properly integrated into the parent's structure once formed. # Returns Returns an instance of `Former2`, a subformer ready to begin the formation process for `{0}` entities, -allowing for dynamic and flexible construction of the `{stru}` entity's {field_ident}. +allowing for dynamic and flexible construction of the `{item}` entity's {field_ident}. "#, format!( "{}", qt!{ #field_typ } ), @@ -928,12 +945,12 @@ allowing for dynamic and flexible construction of the `{stru}` entity's {field_i let doc = format! ( r#" -Provides a user-friendly interface to add an instancce of {field_ident} to the {stru}. +Provides a user-friendly interface to add an instancce of {field_ident} to the {item}. # Returns Returns an instance of `Former2`, a subformer ready to begin the formation process for `{0}` entities, -allowing for dynamic and flexible construction of the `{stru}` entity's {field_ident}. +allowing for dynamic and flexible construction of the `{item}` entity's {field_ident}. "#, format!( "{}", qt!{ #field_typ } ), @@ -992,7 +1009,7 @@ where #[ inline( always ) ] pub fn {field_ident}( self ) -> {0}AsSubformer< Self, impl {0}AsSubformerEnd< Self > > {{ - self.{subform_entry_name}::< {0}Former< _ >, _, >() + self.{subform_entry}::< {0}Former< _ >, _, >() }} // Replace {0} with name of type of entry value. @@ -1003,7 +1020,7 @@ where let about = format! ( r#"derive : Former -item : {stru} +item : {item} field : {field_ident}"#, ); diag::report_print( about, original_input, debug ); @@ -1014,11 +1031,11 @@ field : {field_ident}"#, r#" Implements the `FormingEnd` trait for `{subform_entry_end}` to handle the final -stage of the forming process for a `{stru}` collection that contains `{0}` elements. +stage of the forming process for a `{item}` collection that contains `{0}` elements. This implementation is tailored to manage the transition of {field_ident} elements from a substorage -temporary state into their final state within the `{stru}`'s storage. The function ensures -that the `{stru}`'s {field_ident} storage is initialized if not already set, and then adds the +temporary state into their final state within the `{item}`'s storage. The function ensures +that the `{item}`'s {field_ident} storage is initialized if not already set, and then adds the preformed elements to this storage. # Type Parameters @@ -1037,7 +1054,7 @@ preformed elements to this storage. # Returns Returns the updated `{former}` instance with newly added {field_ident}, completing the -formation process of the `{stru}`. +formation process of the `{item}`. "#, format!( "{}", qt!{ #field_typ } ), @@ -1071,7 +1088,7 @@ formation process of the `{stru}`. where Definition : former::FormerDefinition < - Storage = < #stru < #struct_generics_ty > as former::EntityToStorage >::Storage, + Storage = < #item < #struct_generics_ty > as former::EntityToStorage >::Storage, >, Types2 : former::FormerDefinitionTypes < @@ -1122,7 +1139,7 @@ formation process of the `{stru}`. pub fn subform_scalar_setter ( &self, - stru : &syn::Ident, + item : &syn::Ident, former : &syn::Ident, _former_storage : &syn::Ident, former_generics_ty : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, @@ -1143,22 +1160,29 @@ formation process of the `{stru}`. // example : `children` let setter_name = self.subform_scalar_setter_name(); - // example : `ParentSubformScalarChildrenEnd`` - let subform_scalar_end_name = format!( "{}SubformScalar{}End", stru, field_ident.to_string().to_case( Case::Pascal ) ); - let subform_scalar_end = syn::Ident::new( &subform_scalar_end_name, field_ident.span() ); + // example : `ParentSubformScalarChildrenEnd` + let subform_scalar_end = format_ident! + { + "{}SubformScalar{}End", + item, + field_ident.to_string().to_case( Case::Pascal ) + }; // example : `_children_subform_scalar` - let subform_scalar_name = format!( "_{}_subform_scalar", field_ident ); - let subform_scalar = syn::Ident::new( &subform_scalar_name, field_ident.span() ); + let subform_scalar = format_ident! + { + "_{}_subform_scalar", + field_ident + }; let doc = format! ( r#" -Initiates the scalar subformer for a `{0}` entity within a `{stru}`. +Initiates the scalar subformer for a `{0}` entity within a `{item}`. This function creates a subformer specifically for handling scalar values associated with a `{0}` entity, -leveraging a dedicated end structure to integrate the formed value seamlessly back into the `{stru}`. +leveraging a dedicated end structure to integrate the formed value seamlessly back into the `{item}`. ## Type Parameters @@ -1169,7 +1193,7 @@ leveraging a dedicated end structure to integrate the formed value seamlessly ba - `Former2`: An instance of the former configured to handle the scalar formation of a `{0}`. -This method prepares the forming context, ensuring that the subforming process for a scalar field in `{stru}` +This method prepares the forming context, ensuring that the subforming process for a scalar field in `{item}` is properly initialized with all necessary configurations, including the default end action for integration. ## Usage @@ -1237,14 +1261,14 @@ generics, providing a cleaner interface for initiating subform operations on sca let doc = format! ( r#" -Provides a user-friendly interface to begin subforming a scalar `{0}` field within a `{stru}`. +Provides a user-friendly interface to begin subforming a scalar `{0}` field within a `{item}`. This method abstracts the underlying complex generics involved in setting up the former, simplifying the user interaction needed to initiate the subform process for a scalar field associated with a `{0}`. This method utilizes the more generic `{subform_scalar}` method to set up and return the subformer, providing a straightforward and type-safe interface for client code. It encapsulates details about the specific -former and end action types, ensuring a seamless developer experience when forming parts of a `{stru}`. +former and end action types, ensuring a seamless developer experience when forming parts of a `{item}`. "#, format!( "{}", qt!{ #field_typ } ), @@ -1295,7 +1319,7 @@ former and end action types, ensuring a seamless developer experience when formi impl< Definition > {former}< Definition > where - Definition : former::FormerDefinition< Storage = < {stru} as former::EntityToStorage >::Storage >, + Definition : former::FormerDefinition< Storage = < {item} as former::EntityToStorage >::Storage >, {{ #[ inline( always ) ] pub fn {field_ident}( self, name : &str ) -> {0}AsSubformer< Self, impl {0}AsSubformerEnd< Self > > @@ -1309,7 +1333,7 @@ where let about = format! ( r#"derive : Former -item : {stru} +item : {item} field : {field_ident}"#, ); diag::report_print( about, original_input, debug ); @@ -1319,7 +1343,7 @@ field : {field_ident}"#, ( r#" -Represents the endpoint for the forming process of a scalar field managed by a subformer within a `{stru}` entity. +Represents the endpoint for the forming process of a scalar field managed by a subformer within a `{item}` entity. This structure is a critical component of the forming process when using a subform scalar setter. It handles the finalization of the scalar field's value that has been configured through its dedicated subformer. @@ -1327,13 +1351,13 @@ Essentially, this end action integrates the individually formed scalar value bac ## Type Parameters -- `Definition`: The type that defines the former setup for the `{stru}` entity, influencing storage and behavior during forming. +- `Definition`: The type that defines the former setup for the `{item}` entity, influencing storage and behavior during forming. ## Parameters of `call` - `substorage`: Storage type specific to the `{0}`, containing the newly formed scalar value. - `super_former`: An optional context of the `{former}`, which will receive the value. The function ensures - that this context is not `None` and inserts the formed value into the designated field within `{stru}`'s storage. + that this context is not `None` and inserts the formed value into the designated field within `{item}`'s storage. "#, format!( "{}", qt!{ #field_typ } ), @@ -1366,7 +1390,7 @@ Essentially, this end action integrates the individually formed scalar value bac where Definition : former::FormerDefinition < - Storage = < #stru < #struct_generics_ty > as former::EntityToStorage >::Storage, + Storage = < #item < #struct_generics_ty > as former::EntityToStorage >::Storage, >, Types2 : former::FormerDefinitionTypes < diff --git a/module/core/macro_tools/src/lib.rs b/module/core/macro_tools/src/lib.rs index b1ababf64b..85bafc8eb4 100644 --- a/module/core/macro_tools/src/lib.rs +++ b/module/core/macro_tools/src/lib.rs @@ -170,18 +170,23 @@ pub mod prelude #[ doc( inline ) ] #[ allow( unused_imports ) ] pub use ::syn; + #[ doc( inline ) ] #[ allow( unused_imports ) ] pub use ::proc_macro2; + #[ doc( inline ) ] #[ allow( unused_imports ) ] pub use ::quote; + #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use ::quote::quote as qt; - #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use ::syn::parse_quote as parse_qt; + pub use ::quote:: + { + quote as qt, + format_ident, + }; + #[ doc( inline ) ] #[ allow( unused_imports ) ] pub use ::syn::spanned::Spanned; @@ -199,7 +204,9 @@ pub mod prelude parenthesized, parse_macro_input, parse_quote, + parse_quote as parse_qt, parse_quote_spanned, + parse_quote_spanned as parse_qt_spanned, }; #[ doc( inline ) ] From cfbedf033d91722e5f1a98786847b590d990905a Mon Sep 17 00:00:00 2001 From: wandalen Date: Wed, 29 May 2024 11:09:11 +0300 Subject: [PATCH 25/59] macro_tools : better documentation --- module/core/macro_tools/src/attr.rs | 47 ++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/module/core/macro_tools/src/attr.rs b/module/core/macro_tools/src/attr.rs index a0bb4fbd30..4524ded53e 100644 --- a/module/core/macro_tools/src/attr.rs +++ b/module/core/macro_tools/src/attr.rs @@ -321,17 +321,22 @@ pub( crate ) mod private } } - /// Trait for components of strcuture aggregating attributes that can be constructed from a meta attribute. + /// Trait for components of a structure aggregating attributes that can be constructed from a meta attribute. /// /// The `AttributeComponent` trait defines the interface for components that can be created /// from a `syn::Attribute` meta item. Implementors of this trait are required to define /// a constant `KEYWORD` that identifies the type of the component and a method `from_meta` /// that handles the construction of the component from the given attribute. /// + /// This trait is designed to facilitate modular and reusable parsing of attributes applied + /// to structs, enums, or other constructs. By implementing this trait, you can create specific + /// components from attributes and then aggregate these components into a larger structure. + /// /// # Example /// /// ```rust /// use macro_tools::{ AttributeComponent, Result }; + /// use syn::{ Attribute, Error }; /// /// struct MyComponent; /// @@ -339,14 +344,24 @@ pub( crate ) mod private /// { /// const KEYWORD : &'static str = "my_component"; /// - /// fn from_meta( attr : &syn::Attribute ) -> Result< Self > + /// fn from_meta( attr : &Attribute ) -> Result /// { /// // Parsing logic here + /// // Return Ok(MyComponent) if parsing is successful + /// // Return Err(Error::new_spanned(attr, "error message")) if parsing fails /// Ok( MyComponent ) /// } /// } /// ``` - /// xxx : improve documentation + /// + /// # Parameters + /// + /// - `attr` : A reference to the `syn::Attribute` from which the component is to be constructed. + /// + /// # Returns + /// + /// A `Result` containing the constructed component if successful, or an error if the parsing fails. + /// pub trait AttributeComponent where Self : Sized, @@ -373,14 +388,36 @@ pub( crate ) mod private fn from_meta( attr : &syn::Attribute ) -> Result< Self >; } - /// xxx : write documentation + /// Trait for properties of an attribute component that can be identified by a keyword. + /// + /// The `AttributePropertyComponent` trait defines the interface for attribute properties + /// that can be identified by a specific keyword. Implementors of this trait are required + /// to define a constant `KEYWORD` that identifies the type of the property. + /// + /// This trait is useful in scenarios where attributes may have multiple properties + /// that need to be parsed and handled separately. By defining a unique keyword for each property, + /// the parsing logic can accurately identify and process each property. + /// + /// # Example + /// + /// ```rust + /// use macro_tools::AttributePropertyComponent; + /// + /// struct MyProperty; + /// + /// impl AttributePropertyComponent for MyProperty + /// { + /// const KEYWORD : &'static str = "my_property"; + /// } + /// ``` + /// pub trait AttributePropertyComponent where Self : Sized, { /// The keyword that identifies the component. /// - /// This constant is used to match the attribute to the corresponding component. + /// This constant is used to match the attribute to the corresponding property. /// Each implementor of this trait must provide a unique keyword for its type. const KEYWORD : &'static str; } From a8b2223f3a272dc3c2a1c22f40ee1e8b4632826c Mon Sep 17 00:00:00 2001 From: wandalen Date: Wed, 29 May 2024 11:24:03 +0300 Subject: [PATCH 26/59] macroses : use AttributePropertyOptionalSingletone instead of AttributePropertySingletone --- .../core/derive_tools_meta/src/derive/from.rs | 29 +++++++++-------- module/core/former_meta/src/derive_former.rs | 4 +-- .../former_meta/src/derive_former/field.rs | 8 ++--- .../src/derive_former/field_attrs.rs | 32 +++++++++---------- .../src/derive_former/struct_attrs.rs | 14 ++++---- module/core/macro_tools/src/attr_prop.rs | 4 +-- .../src/attr_prop/singletone_optional.rs | 22 ++++++------- .../macro_tools/tests/inc/attr_prop_test.rs | 2 +- 8 files changed, 58 insertions(+), 57 deletions(-) diff --git a/module/core/derive_tools_meta/src/derive/from.rs b/module/core/derive_tools_meta/src/derive/from.rs index 818d20c40c..aa1840bd31 100644 --- a/module/core/derive_tools_meta/src/derive/from.rs +++ b/module/core/derive_tools_meta/src/derive/from.rs @@ -9,7 +9,8 @@ use macro_tools:: Result, AttributeComponent, AttributePropertyComponent, - AttributePropertySingletone, + // AttributePropertySingletone, + AttributePropertyOptionalSingletone, }; use former_types::ComponentAssign; @@ -190,7 +191,7 @@ fn variant_generate ) }; - if attrs.config.debug.into() + if attrs.config.debug.value( false ) { let debug = format! ( @@ -547,8 +548,8 @@ impl syn::parse::Parse for ItemAttributeConfig let known = const_format::concatcp! ( "Known entries of attribute ", ItemAttributeConfig::KEYWORD, " are : ", - AttributePropertyEnabledMarker::KEYWORD_ON, - ", ", AttributePropertyEnabledMarker::KEYWORD_OFF, + EnabledMarker::KEYWORD_ON, + ", ", EnabledMarker::KEYWORD_OFF, ".", ); syn_err! @@ -570,8 +571,8 @@ impl syn::parse::Parse for ItemAttributeConfig let ident : syn::Ident = input.parse()?; match ident.to_string().as_str() { - AttributePropertyEnabledMarker::KEYWORD_ON => result.assign( AttributePropertyEnabled::from( true ) ), - AttributePropertyEnabledMarker::KEYWORD_OFF => result.assign( AttributePropertyEnabled::from( false ) ), + EnabledMarker::KEYWORD_ON => result.assign( AttributePropertyEnabled::from( true ) ), + EnabledMarker::KEYWORD_OFF => result.assign( AttributePropertyEnabled::from( false ) ), _ => return Err( error( &ident ) ), } } @@ -739,8 +740,8 @@ impl syn::parse::Parse for FieldAttributeConfig ( "Known entries of attribute ", FieldAttributeConfig::KEYWORD, " are : ", AttributePropertyDebug::KEYWORD, - ", ", AttributePropertyEnabledMarker::KEYWORD_ON, - ", ", AttributePropertyEnabledMarker::KEYWORD_OFF, + ", ", EnabledMarker::KEYWORD_ON, + ", ", EnabledMarker::KEYWORD_OFF, ".", ); syn_err! @@ -763,8 +764,8 @@ impl syn::parse::Parse for FieldAttributeConfig match ident.to_string().as_str() { AttributePropertyDebug::KEYWORD => result.assign( AttributePropertyDebug::from( true ) ), - AttributePropertyEnabledMarker::KEYWORD_ON => result.assign( AttributePropertyEnabled::from( true ) ), - AttributePropertyEnabledMarker::KEYWORD_OFF => result.assign( AttributePropertyEnabled::from( false ) ), + EnabledMarker::KEYWORD_ON => result.assign( AttributePropertyEnabled::from( true ) ), + EnabledMarker::KEYWORD_OFF => result.assign( AttributePropertyEnabled::from( false ) ), _ => return Err( error( &ident ) ), } } @@ -798,15 +799,15 @@ impl AttributePropertyComponent for AttributePropertyDebugMarker /// Specifies whether to provide a generated code as a hint. /// Defaults to `false`, which means no debug is provided unless explicitly requested. -pub type AttributePropertyDebug = AttributePropertySingletone< AttributePropertyDebugMarker >; +pub type AttributePropertyDebug = AttributePropertyOptionalSingletone< AttributePropertyDebugMarker >; // = /// Marker type for attribute property to indicates whether `From` implementation for fields/variants should be generated. #[ derive( Debug, Default, Clone, Copy ) ] -pub struct AttributePropertyEnabledMarker; +pub struct EnabledMarker; -impl AttributePropertyEnabledMarker +impl EnabledMarker { /// Keywords for parsing this attribute property. pub const KEYWORD_OFF : &'static str = "off"; @@ -816,6 +817,6 @@ impl AttributePropertyEnabledMarker /// Specifies whether `From` implementation for fields/variants should be generated. /// Can be altered using `on` and `off` attributes. But default it's `on`. -pub type AttributePropertyEnabled = macro_tools::AttributePropertyEnabled< AttributePropertyEnabledMarker >; +pub type AttributePropertyEnabled = AttributePropertyOptionalSingletone< EnabledMarker >; // == diff --git a/module/core/former_meta/src/derive_former.rs b/module/core/former_meta/src/derive_former.rs index ac2be6c48f..d79534fb02 100644 --- a/module/core/former_meta/src/derive_former.rs +++ b/module/core/former_meta/src/derive_former.rs @@ -53,7 +53,7 @@ pub fn mutator ) -> Result< TokenStream > { - let former_mutator_code = if mutator.custom.into() + let former_mutator_code = if mutator.custom.value( false ) { qt!{} } @@ -70,7 +70,7 @@ pub fn mutator } }; - if mutator.debug.into() + if mutator.debug.value( false ) { let debug = format! ( diff --git a/module/core/former_meta/src/derive_former/field.rs b/module/core/former_meta/src/derive_former/field.rs index c04845e31f..13a702b308 100644 --- a/module/core/former_meta/src/derive_former/field.rs +++ b/module/core/former_meta/src/derive_former/field.rs @@ -456,7 +456,7 @@ scalar_setter_required let setter_name = self.scalar_setter_name(); let attr = self.attrs.scalar.as_ref(); - if attr.is_some() && attr.unwrap().debug.into() + if attr.is_some() && attr.unwrap().debug.value( false ) { let debug = format! ( @@ -692,7 +692,7 @@ field : {field_ident}"#, qt!{} }; - if attr.debug.into() + if attr.debug.value( false ) { let debug = format! ( @@ -992,7 +992,7 @@ allowing for dynamic and flexible construction of the `{item}` entity's {field_i setters_code }; - if attr.debug.into() + if attr.debug.value( false ) { let debug = format! ( @@ -1309,7 +1309,7 @@ former and end action types, ensuring a seamless developer experience when formi setters_code }; - if attr.debug.into() + if attr.debug.value( false ) { let debug = format! ( diff --git a/module/core/former_meta/src/derive_former/field_attrs.rs b/module/core/former_meta/src/derive_former/field_attrs.rs index f926833647..4c59182a72 100644 --- a/module/core/former_meta/src/derive_former/field_attrs.rs +++ b/module/core/former_meta/src/derive_former/field_attrs.rs @@ -9,7 +9,7 @@ use macro_tools:: AttributePropertyComponent, AttributePropertyOptionalBoolean, AttributePropertyOptionalSyn, - AttributePropertySingletone, + AttributePropertyOptionalSingletone, }; use former_types::{ ComponentAssign }; @@ -883,76 +883,76 @@ impl syn::parse::Parse for AttributeSubformEntrySetter /// Marker type for attribute property to specify whether to provide a sketch as a hint. /// Defaults to `false`, which means no hint is provided unless explicitly requested. #[ derive( Debug, Default, Clone, Copy ) ] -pub struct AttributePropertyDebugMarker; +pub struct DebugMarker; /// Specifies whether to provide a sketch as a hint. /// Defaults to `false`, which means no hint is provided unless explicitly requested. -impl AttributePropertyComponent for AttributePropertyDebugMarker +impl AttributePropertyComponent for DebugMarker { const KEYWORD : &'static str = "debug"; } /// Specifies whether to provide a sketch as a hint. /// Defaults to `false`, which means no hint is provided unless explicitly requested. -pub type AttributePropertyDebug = AttributePropertySingletone< AttributePropertyDebugMarker >; +pub type AttributePropertyDebug = AttributePropertyOptionalSingletone< DebugMarker >; // = /// Disable generation of setter. /// Attributes still might generate some helper methods to reuse by custom setter. #[ derive( Debug, Default, Clone, Copy ) ] -pub struct AttributePropertySetterMarker; +pub struct SetterMarker; -impl AttributePropertyComponent for AttributePropertySetterMarker +impl AttributePropertyComponent for SetterMarker { const KEYWORD : &'static str = "setter"; } /// Disable generation of setter. /// Attributes still might generate some helper methods to reuse by custom setter. -pub type AttributePropertySetter = AttributePropertyOptionalBoolean< AttributePropertySetterMarker >; +pub type AttributePropertySetter = AttributePropertyOptionalBoolean< SetterMarker >; // = /// Marker type for attribute property of optional identifier that names the setter. It is parsed from inputs /// like `name = my_field`. #[ derive( Debug, Default, Clone, Copy ) ] -pub struct AttributePropertyNameMarker; +pub struct NameMarker; -impl AttributePropertyComponent for AttributePropertyNameMarker +impl AttributePropertyComponent for NameMarker { const KEYWORD : &'static str = "name"; } /// An optional identifier that names the setter. It is parsed from inputs /// like `name = my_field`. -pub type AttributePropertyName = AttributePropertyOptionalSyn< syn::Ident, AttributePropertyNameMarker >; +pub type AttributePropertyName = AttributePropertyOptionalSyn< syn::Ident, NameMarker >; // = /// Marker type for default value to use for a field. #[ derive( Debug, Default, Clone, Copy ) ] -pub struct AttributePropertyDefaultMarker; +pub struct DefaultMarker; -impl AttributePropertyComponent for AttributePropertyDefaultMarker +impl AttributePropertyComponent for DefaultMarker { const KEYWORD : &'static str = "default"; } /// An optional identifier that names the setter. It is parsed from inputs /// like `name = my_field`. -pub type AttributePropertyDefault = AttributePropertyOptionalSyn< syn::Expr, AttributePropertyDefaultMarker >; +pub type AttributePropertyDefault = AttributePropertyOptionalSyn< syn::Expr, DefaultMarker >; // = /// Marker type for definition of the collection former to use, e.g., `former::VectorFormer`. #[ derive( Debug, Default, Clone, Copy ) ] -pub struct AttributePropertyDefinitionMarker; +pub struct DefinitionMarker; -impl AttributePropertyComponent for AttributePropertyDefinitionMarker +impl AttributePropertyComponent for DefinitionMarker { const KEYWORD : &'static str = "definition"; } /// Definition of the collection former to use, e.g., `former::VectorFormer`. -pub type AttributePropertyDefinition = AttributePropertyOptionalSyn< syn::Type, AttributePropertyDefinitionMarker >; +pub type AttributePropertyDefinition = AttributePropertyOptionalSyn< syn::Type, DefinitionMarker >; diff --git a/module/core/former_meta/src/derive_former/struct_attrs.rs b/module/core/former_meta/src/derive_former/struct_attrs.rs index 1c63833cdb..211b9abfc9 100644 --- a/module/core/former_meta/src/derive_former/struct_attrs.rs +++ b/module/core/former_meta/src/derive_former/struct_attrs.rs @@ -10,7 +10,7 @@ use macro_tools:: Result, AttributeComponent, AttributePropertyComponent, - AttributePropertySingletone, + AttributePropertyOptionalSingletone, }; use former_types::{ ComponentAssign }; @@ -415,29 +415,29 @@ where /// Marker type for attribute property to specify whether to provide a sketch as a hint. /// Defaults to `false`, which means no hint is provided unless explicitly requested. #[ derive( Debug, Default, Clone, Copy ) ] -pub struct AttributePropertyDebugMarker; +pub struct DebugMarker; -impl AttributePropertyComponent for AttributePropertyDebugMarker +impl AttributePropertyComponent for DebugMarker { const KEYWORD : &'static str = "debug"; } /// Specifies whether to provide a sketch as a hint. /// Defaults to `false`, which means no hint is provided unless explicitly requested. -pub type AttributePropertyDebug = AttributePropertySingletone< AttributePropertyDebugMarker >; +pub type AttributePropertyDebug = AttributePropertyOptionalSingletone< DebugMarker >; // = /// Marker type for attribute property to indicates whether a custom code should be generated. /// Defaults to `false`, meaning no custom code is generated unless explicitly requested. #[ derive( Debug, Default, Clone, Copy ) ] -pub struct AttributePropertyCustomMarker; +pub struct CustomMarker; -impl AttributePropertyComponent for AttributePropertyCustomMarker +impl AttributePropertyComponent for CustomMarker { const KEYWORD : &'static str = "custom"; } /// Indicates whether a custom code should be generated. /// Defaults to `false`, meaning no custom code is generated unless explicitly requested. -pub type AttributePropertyCustom = AttributePropertySingletone< AttributePropertyCustomMarker >; +pub type AttributePropertyCustom = AttributePropertyOptionalSingletone< CustomMarker >; diff --git a/module/core/macro_tools/src/attr_prop.rs b/module/core/macro_tools/src/attr_prop.rs index cb515c4217..1435cbbeed 100644 --- a/module/core/macro_tools/src/attr_prop.rs +++ b/module/core/macro_tools/src/attr_prop.rs @@ -147,8 +147,8 @@ pub mod exposed { singletone::AttributePropertySingletone, singletone::AttributePropertySingletoneMarker, - singletone_optional::AttributePropertyEnabled, - singletone_optional::AttributePropertyEnabledMarker, + singletone_optional::AttributePropertyOptionalSingletone, + singletone_optional::AttributePropertyOptionalSingletoneMarker, boolean::AttributePropertyBoolean, boolean_optional::AttributePropertyOptionalBoolean, diff --git a/module/core/macro_tools/src/attr_prop/singletone_optional.rs b/module/core/macro_tools/src/attr_prop/singletone_optional.rs index ad388db1c6..b7cfe83bad 100644 --- a/module/core/macro_tools/src/attr_prop/singletone_optional.rs +++ b/module/core/macro_tools/src/attr_prop/singletone_optional.rs @@ -15,10 +15,10 @@ use crate::*; -/// Default marker for `AttributePropertyEnabled`. +/// Default marker for `AttributePropertyOptionalSingletone`. /// Used if no marker is defined as parameter. #[ derive( Debug, Default, Clone, Copy ) ] -pub struct AttributePropertyEnabledMarker; +pub struct AttributePropertyOptionalSingletoneMarker; /// A generic attribute property for switching on/off. /// Has 3 states: `None`, `Some( true )`, `Some( false )`. @@ -28,13 +28,13 @@ pub struct AttributePropertyEnabledMarker; /// For example: `#[ attribute( on ) ]` and `#[ attribute( off )]`. /// As a consequence, the property has two keywords. #[ derive( Debug, Default, Clone, Copy ) ] -pub struct AttributePropertyEnabled< Marker = AttributePropertyEnabledMarker > +pub struct AttributePropertyOptionalSingletone< Marker = AttributePropertyOptionalSingletoneMarker > ( Option< bool >, ::core::marker::PhantomData< Marker >, ); -impl< Marker > AttributePropertyEnabled< Marker > +impl< Marker > AttributePropertyOptionalSingletone< Marker > { // /// Keywords for parsing this attribute property. @@ -71,14 +71,14 @@ impl< Marker > AttributePropertyEnabled< Marker > } -impl< Marker > AttributePropertyComponent for AttributePropertyEnabled< Marker > +impl< Marker > AttributePropertyComponent for AttributePropertyOptionalSingletone< Marker > where Marker : AttributePropertyComponent, { const KEYWORD : &'static str = Marker::KEYWORD; } -impl< Marker > From< bool > for AttributePropertyEnabled< Marker > +impl< Marker > From< bool > for AttributePropertyOptionalSingletone< Marker > { #[ inline( always ) ] fn from( src : bool ) -> Self @@ -87,7 +87,7 @@ impl< Marker > From< bool > for AttributePropertyEnabled< Marker > } } -impl< Marker > From< Option< bool > > for AttributePropertyEnabled< Marker > +impl< Marker > From< Option< bool > > for AttributePropertyOptionalSingletone< Marker > { #[ inline( always ) ] fn from( src : Option< bool > ) -> Self @@ -96,16 +96,16 @@ impl< Marker > From< Option< bool > > for AttributePropertyEnabled< Marker > } } -impl< Marker > From< AttributePropertyEnabled< Marker > > for Option< bool > +impl< Marker > From< AttributePropertyOptionalSingletone< Marker > > for Option< bool > { #[ inline( always ) ] - fn from( src : AttributePropertyEnabled< Marker > ) -> Self + fn from( src : AttributePropertyOptionalSingletone< Marker > ) -> Self { src.0 } } -impl< Marker > core::ops::Deref for AttributePropertyEnabled< Marker > +impl< Marker > core::ops::Deref for AttributePropertyOptionalSingletone< Marker > { type Target = Option< bool >; @@ -116,7 +116,7 @@ impl< Marker > core::ops::Deref for AttributePropertyEnabled< Marker > } } -impl< Marker > AsRef< Option< bool > > for AttributePropertyEnabled< Marker > +impl< Marker > AsRef< Option< bool > > for AttributePropertyOptionalSingletone< Marker > { #[ inline( always ) ] fn as_ref( &self ) -> &Option< bool > diff --git a/module/core/macro_tools/tests/inc/attr_prop_test.rs b/module/core/macro_tools/tests/inc/attr_prop_test.rs index 223f8be5d4..e2fdb5ecb6 100644 --- a/module/core/macro_tools/tests/inc/attr_prop_test.rs +++ b/module/core/macro_tools/tests/inc/attr_prop_test.rs @@ -105,7 +105,7 @@ fn attr_prop_test() fn attribute_property_enabled() { // Test default value - let attr : AttributePropertyEnabled = Default::default(); + let attr : AttributePropertyOptionalSingletone = Default::default(); assert_eq!( attr.internal(), None ); assert_eq!( attr.value( true ), true ); assert_eq!( attr.value( false ), false ); From 40a707e5c6cc2ad1d71d9027f09c569fb437841c Mon Sep 17 00:00:00 2001 From: wandalen Date: Wed, 29 May 2024 11:57:11 +0300 Subject: [PATCH 27/59] macroses : per-field assign to make possible usage of several attributes of the same type --- .../core/derive_tools_meta/src/derive/from.rs | 4 +++- module/core/macro_tools/Cargo.toml | 7 +++---- .../src/attr_prop/boolean_optional.rs | 14 ++++++++++++++ .../src/attr_prop/singletone_optional.rs | 19 +++++++++++++++++++ 4 files changed, 39 insertions(+), 5 deletions(-) diff --git a/module/core/derive_tools_meta/src/derive/from.rs b/module/core/derive_tools_meta/src/derive/from.rs index aa1840bd31..52b5c649ee 100644 --- a/module/core/derive_tools_meta/src/derive/from.rs +++ b/module/core/derive_tools_meta/src/derive/from.rs @@ -702,7 +702,9 @@ where #[ inline( always ) ] fn assign( &mut self, component : IntoT ) { - self.config = component.into(); + let component = component.into(); + self.config.enabled.assign( component.enabled ); + self.config.debug.assign( component.debug ); } } diff --git a/module/core/macro_tools/Cargo.toml b/module/core/macro_tools/Cargo.toml index b01417bfad..b61e003d48 100644 --- a/module/core/macro_tools/Cargo.toml +++ b/module/core/macro_tools/Cargo.toml @@ -28,7 +28,7 @@ all-features = false [features] default = [ "enabled" ] full = [ "enabled" ] -enabled = [] +enabled = [ "former_types/enabled", "interval_adapter/enabled" ] # qqq : put all files under features: macro_attr, macro_container_kind, ... @@ -40,10 +40,9 @@ quote = { version = "~1.0.35", features = [] } syn = { version = "~2.0.52", features = [ "full", "extra-traits" ] } ## internal -interval_adapter = { workspace = true, features = [ "default" ] } -# strs_tools = { workspace = true, features = [ "default" ] } +interval_adapter = { workspace = true, features = [ "default" ] } # xxx : optimize features list +former_types = { workspace = true, features = [ "types_component_assign" ] } [dev-dependencies] test_tools = { workspace = true } -former_types = { workspace = true, features = [ "enabled", "types_component_assign" ] } const_format = { version = "0.2.32" } diff --git a/module/core/macro_tools/src/attr_prop/boolean_optional.rs b/module/core/macro_tools/src/attr_prop/boolean_optional.rs index d48ebdaf84..a9c84f47e1 100644 --- a/module/core/macro_tools/src/attr_prop/boolean_optional.rs +++ b/module/core/macro_tools/src/attr_prop/boolean_optional.rs @@ -25,6 +25,20 @@ impl< Marker > AttributePropertyOptionalBoolean< Marker > { self.0.as_ref() } + + // xxx + // /// Inserts value of another instance into the option if it is None, then returns a mutable reference to the contained value. + // /// If another instance does is None then do nothing. + // #[ inline( always ) ] + // pub fn get_or_insert2( &mut self, another : Self ) + // { + // match another.0 + // { + // Some( val ) => { self.0.get_or_insert( val ); }, + // None => {}, + // } + // } + } impl< Marker > AttributePropertyComponent for AttributePropertyOptionalBoolean< Marker > diff --git a/module/core/macro_tools/src/attr_prop/singletone_optional.rs b/module/core/macro_tools/src/attr_prop/singletone_optional.rs index b7cfe83bad..63a4e11548 100644 --- a/module/core/macro_tools/src/attr_prop/singletone_optional.rs +++ b/module/core/macro_tools/src/attr_prop/singletone_optional.rs @@ -14,6 +14,7 @@ //! This is useful for attributes that need to enable or disable features or flags. use crate::*; +use former_types::ComponentAssign; /// Default marker for `AttributePropertyOptionalSingletone`. /// Used if no marker is defined as parameter. @@ -71,6 +72,24 @@ impl< Marker > AttributePropertyOptionalSingletone< Marker > } +impl< Marker, IntoT > ComponentAssign< AttributePropertyOptionalSingletone< Marker >, IntoT > for AttributePropertyOptionalSingletone< Marker > +where + IntoT : Into< AttributePropertyOptionalSingletone< Marker > >, +{ + /// Inserts value of another instance into the option if it is None, then returns a mutable reference to the contained value. + /// If another instance does is None then do nothing. + #[ inline( always ) ] + fn assign( &mut self, component : IntoT ) + { + let component = component.into(); + match component.0 + { + Some( val ) => { self.0.get_or_insert( val ); }, + None => {}, + } + } +} + impl< Marker > AttributePropertyComponent for AttributePropertyOptionalSingletone< Marker > where Marker : AttributePropertyComponent, From 7069a4daf80c359d08a19caadd39ac074ee82ebe Mon Sep 17 00:00:00 2001 From: wandalen Date: Wed, 29 May 2024 12:00:52 +0300 Subject: [PATCH 28/59] macroses : per-field assign to make possible usage of several attributes of the same type --- .../src/attr_prop/boolean_optional.rs | 31 ++++++++++++------- .../src/attr_prop/singletone_optional.rs | 10 ++---- .../macro_tools/src/attr_prop/syn_optional.rs | 21 +++++++++++++ 3 files changed, 42 insertions(+), 20 deletions(-) diff --git a/module/core/macro_tools/src/attr_prop/boolean_optional.rs b/module/core/macro_tools/src/attr_prop/boolean_optional.rs index a9c84f47e1..3c288d8c97 100644 --- a/module/core/macro_tools/src/attr_prop/boolean_optional.rs +++ b/module/core/macro_tools/src/attr_prop/boolean_optional.rs @@ -4,6 +4,7 @@ //! use crate::*; +use former_types::ComponentAssign; /// A generic optional boolean attribute property: `Option< bool >`. /// Defaults to `false`. @@ -26,19 +27,25 @@ impl< Marker > AttributePropertyOptionalBoolean< Marker > self.0.as_ref() } - // xxx - // /// Inserts value of another instance into the option if it is None, then returns a mutable reference to the contained value. - // /// If another instance does is None then do nothing. - // #[ inline( always ) ] - // pub fn get_or_insert2( &mut self, another : Self ) - // { - // match another.0 - // { - // Some( val ) => { self.0.get_or_insert( val ); }, - // None => {}, - // } - // } +} +impl< Marker, IntoT > ComponentAssign< AttributePropertyOptionalBoolean< Marker >, IntoT > +for AttributePropertyOptionalBoolean< Marker > +where + IntoT : Into< AttributePropertyOptionalBoolean< Marker > >, +{ + /// Inserts value of another instance into the option if it is None, then returns a mutable reference to the contained value. + /// If another instance does is None then do nothing. + #[ inline( always ) ] + fn assign( &mut self, component : IntoT ) + { + let component = component.into(); + match component.0 + { + Some( val ) => { self.0.get_or_insert( val ); }, + None => {}, + } + } } impl< Marker > AttributePropertyComponent for AttributePropertyOptionalBoolean< Marker > diff --git a/module/core/macro_tools/src/attr_prop/singletone_optional.rs b/module/core/macro_tools/src/attr_prop/singletone_optional.rs index 63a4e11548..b99a71b2c4 100644 --- a/module/core/macro_tools/src/attr_prop/singletone_optional.rs +++ b/module/core/macro_tools/src/attr_prop/singletone_optional.rs @@ -38,13 +38,6 @@ pub struct AttributePropertyOptionalSingletone< Marker = AttributePropertyOption impl< Marker > AttributePropertyOptionalSingletone< Marker > { - // /// Keywords for parsing this attribute property. - // pub const KEYWORDS : [ &'static str ; 2 ] = [ "on", "off" ]; - // /// Keywords for parsing this attribute property. - // pub const KEYWORD_OFF : &'static str = "off"; - // /// Keywords for parsing this attribute property. - // pub const KEYWORD_ON : &'static str = "on"; - /// Return bool value: on/off, use argument as default if it's `None`. #[ inline ] pub fn value( self, default : bool ) -> bool @@ -72,7 +65,8 @@ impl< Marker > AttributePropertyOptionalSingletone< Marker > } -impl< Marker, IntoT > ComponentAssign< AttributePropertyOptionalSingletone< Marker >, IntoT > for AttributePropertyOptionalSingletone< Marker > +impl< Marker, IntoT > ComponentAssign< AttributePropertyOptionalSingletone< Marker >, IntoT > +for AttributePropertyOptionalSingletone< Marker > where IntoT : Into< AttributePropertyOptionalSingletone< Marker > >, { diff --git a/module/core/macro_tools/src/attr_prop/syn_optional.rs b/module/core/macro_tools/src/attr_prop/syn_optional.rs index 9233b49709..e6e2e723c6 100644 --- a/module/core/macro_tools/src/attr_prop/syn_optional.rs +++ b/module/core/macro_tools/src/attr_prop/syn_optional.rs @@ -3,6 +3,7 @@ //! use crate::*; +use former_types::ComponentAssign; /// /// Property of an attribute which simply wraps one of the standard `syn` types and keeps it optional. @@ -32,6 +33,26 @@ where } } +impl< T, Marker, IntoT > ComponentAssign< AttributePropertyOptionalSyn< T, Marker >, IntoT > +for AttributePropertyOptionalSyn< T, Marker > +where + T : syn::parse::Parse + quote::ToTokens, + IntoT : Into< AttributePropertyOptionalSyn< T, Marker > >, +{ + /// Inserts value of another instance into the option if it is None, then returns a mutable reference to the contained value. + /// If another instance does is None then do nothing. + #[ inline( always ) ] + fn assign( &mut self, component : IntoT ) + { + let component = component.into(); + match component.0 + { + Some( val ) => { self.0.get_or_insert( val ); }, + None => {}, + } + } +} + impl< T, Marker > AttributePropertyComponent for AttributePropertyOptionalSyn< T, Marker > where T : syn::parse::Parse + quote::ToTokens, From 5b6407e2c7b510a7c6d4da58cad255e3578aa33a Mon Sep 17 00:00:00 2001 From: wandalen Date: Wed, 29 May 2024 12:07:29 +0300 Subject: [PATCH 29/59] macroses : per-field assign to make possible usage of several attributes of the same type --- module/core/macro_tools/src/attr_prop/boolean.rs | 15 +++++++++++++++ .../core/macro_tools/src/attr_prop/singletone.rs | 13 +++++++++++++ module/core/macro_tools/src/attr_prop/syn.rs | 14 ++++++++++++++ 3 files changed, 42 insertions(+) diff --git a/module/core/macro_tools/src/attr_prop/boolean.rs b/module/core/macro_tools/src/attr_prop/boolean.rs index 37c54fc0f0..7aa4aeb90f 100644 --- a/module/core/macro_tools/src/attr_prop/boolean.rs +++ b/module/core/macro_tools/src/attr_prop/boolean.rs @@ -4,6 +4,7 @@ //! use crate::*; +use former_types::ComponentAssign; /// A generic boolean attribute property. /// Defaults to `false`. @@ -122,6 +123,20 @@ impl< Marker > AttributePropertyBoolean< Marker > } } +// xxx : introduce default markers for all properties + +impl< Marker, IntoT > ComponentAssign< AttributePropertyBoolean< Marker >, IntoT > +for AttributePropertyBoolean< Marker > +where + IntoT : Into< AttributePropertyBoolean< Marker > >, +{ + #[ inline( always ) ] + fn assign( &mut self, component : IntoT ) + { + *self = component.into(); + } +} + impl< Marker > AttributePropertyComponent for AttributePropertyBoolean< Marker > where Marker : AttributePropertyComponent, diff --git a/module/core/macro_tools/src/attr_prop/singletone.rs b/module/core/macro_tools/src/attr_prop/singletone.rs index 9cbfbc8c3b..1afa7aa52f 100644 --- a/module/core/macro_tools/src/attr_prop/singletone.rs +++ b/module/core/macro_tools/src/attr_prop/singletone.rs @@ -12,6 +12,7 @@ //! This is useful for attributes that need to enable or disable features or flags. use crate::*; +use former_types::ComponentAssign; /// Default marker for `AttributePropertySingletone`. /// Used if no marker is defined as parameter. @@ -49,6 +50,18 @@ impl< Marker > AttributePropertySingletone< Marker > } +impl< Marker, IntoT > ComponentAssign< AttributePropertySingletone< Marker >, IntoT > +for AttributePropertySingletone< Marker > +where + IntoT : Into< AttributePropertySingletone< Marker > >, +{ + #[ inline( always ) ] + fn assign( &mut self, component : IntoT ) + { + *self = component.into(); + } +} + impl< Marker > AttributePropertyComponent for AttributePropertySingletone< Marker > where Marker : AttributePropertyComponent, diff --git a/module/core/macro_tools/src/attr_prop/syn.rs b/module/core/macro_tools/src/attr_prop/syn.rs index 93d9eaad5c..1fc1912532 100644 --- a/module/core/macro_tools/src/attr_prop/syn.rs +++ b/module/core/macro_tools/src/attr_prop/syn.rs @@ -3,6 +3,7 @@ //! use crate::*; +use former_types::ComponentAssign; /// /// Property of an attribute which simply wraps one of the standard `syn` types. @@ -34,6 +35,19 @@ where } } +impl< T, Marker, IntoT > ComponentAssign< AttributePropertySyn< T, Marker >, IntoT > +for AttributePropertySyn< T, Marker > +where + T : syn::parse::Parse + quote::ToTokens, + IntoT : Into< AttributePropertySyn< T, Marker > >, +{ + #[ inline( always ) ] + fn assign( &mut self, component : IntoT ) + { + *self = component.into(); + } +} + impl< T, Marker > AttributePropertyComponent for AttributePropertySyn< T, Marker > where T : syn::parse::Parse + quote::ToTokens, From 41b59fd7f4b0789c05a40b3b92063c6f1555d24f Mon Sep 17 00:00:00 2001 From: wandalen Date: Wed, 29 May 2024 12:09:35 +0300 Subject: [PATCH 30/59] macroses : per-field assign to make possible usage of several attributes of the same type --- module/core/macro_tools/Cargo.toml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/module/core/macro_tools/Cargo.toml b/module/core/macro_tools/Cargo.toml index b61e003d48..d8e4f0ab55 100644 --- a/module/core/macro_tools/Cargo.toml +++ b/module/core/macro_tools/Cargo.toml @@ -39,8 +39,10 @@ proc-macro2 = { version = "~1.0.78", features = [] } quote = { version = "~1.0.35", features = [] } syn = { version = "~2.0.52", features = [ "full", "extra-traits" ] } +# xxx : optimize features list + ## internal -interval_adapter = { workspace = true, features = [ "default" ] } # xxx : optimize features list +interval_adapter = { workspace = true, features = [] } former_types = { workspace = true, features = [ "types_component_assign" ] } [dev-dependencies] From 2ac07584da2bf7a6ad7c8848438458b32d10301d Mon Sep 17 00:00:00 2001 From: wandalen Date: Thu, 30 May 2024 07:35:22 +0300 Subject: [PATCH 31/59] derive_tools, former: implementing ComponentAssign for all attributes --- .../core/derive_tools_meta/src/derive/from.rs | 18 ++++++++++++++++-- module/core/macro_tools/Cargo.toml | 2 +- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/module/core/derive_tools_meta/src/derive/from.rs b/module/core/derive_tools_meta/src/derive/from.rs index 52b5c649ee..5bcae1702c 100644 --- a/module/core/derive_tools_meta/src/derive/from.rs +++ b/module/core/derive_tools_meta/src/derive/from.rs @@ -696,6 +696,20 @@ impl AttributeComponent for FieldAttributeConfig } impl< IntoT > ComponentAssign< FieldAttributeConfig, IntoT > for FieldAttributes +where + IntoT : Into< FieldAttributeConfig >, +{ + #[ inline( always ) ] + fn assign( &mut self, component : IntoT ) + { + self.config.assign( component.into() ); + // let component = component.into(); + // self.config.enabled.assign( component.enabled ); + // self.config.debug.assign( component.debug ); + } +} + +impl< IntoT > ComponentAssign< FieldAttributeConfig, IntoT > for FieldAttributeConfig where IntoT : Into< FieldAttributeConfig >, { @@ -703,8 +717,8 @@ where fn assign( &mut self, component : IntoT ) { let component = component.into(); - self.config.enabled.assign( component.enabled ); - self.config.debug.assign( component.debug ); + self.enabled.assign( component.enabled ); + self.debug.assign( component.debug ); } } diff --git a/module/core/macro_tools/Cargo.toml b/module/core/macro_tools/Cargo.toml index d8e4f0ab55..76f03b758d 100644 --- a/module/core/macro_tools/Cargo.toml +++ b/module/core/macro_tools/Cargo.toml @@ -39,7 +39,7 @@ proc-macro2 = { version = "~1.0.78", features = [] } quote = { version = "~1.0.35", features = [] } syn = { version = "~2.0.52", features = [ "full", "extra-traits" ] } -# xxx : optimize features list +# qqq : optimize features list ## internal interval_adapter = { workspace = true, features = [] } From c6420cccf0c250fa6f6a35cc6f223e847f05610a Mon Sep 17 00:00:00 2001 From: wandalen Date: Thu, 30 May 2024 08:24:40 +0300 Subject: [PATCH 32/59] derive_tools, former: implementing ComponentAssign for all attributes --- .../core/derive_tools_meta/src/derive/from.rs | 31 ++++++---- .../inc/components_tests/component_assign.rs | 4 +- .../component_assign_manual.rs | 6 +- .../inc/components_tests/components_assign.rs | 6 +- .../components_assign_manual.rs | 32 +++++----- .../tests/inc/components_tests/composite.rs | 6 +- .../inc/components_tests/composite_manual.rs | 32 +++++----- .../src/component/component_assign.rs | 12 ++-- .../src/component/components_assign.rs | 8 +-- .../src/derive_former/field_attrs.rs | 59 ++++++++++++------- .../src/derive_former/struct_attrs.rs | 12 ++-- module/core/former_meta/src/lib.rs | 58 +++++++++--------- module/core/former_types/Readme.md | 10 ++-- .../examples/former_types_trivial.rs | 12 ++-- module/core/former_types/src/component.rs | 31 +++++++--- module/core/macro_tools/Readme.md | 18 +++--- .../examples/macro_tools_attr_prop.rs | 18 +++--- .../core/macro_tools/src/attr_prop/boolean.rs | 4 +- .../src/attr_prop/boolean_optional.rs | 4 +- .../macro_tools/src/attr_prop/singletone.rs | 4 +- .../src/attr_prop/singletone_optional.rs | 4 +- module/core/macro_tools/src/attr_prop/syn.rs | 4 +- .../macro_tools/src/attr_prop/syn_optional.rs | 4 +- 23 files changed, 209 insertions(+), 170 deletions(-) diff --git a/module/core/derive_tools_meta/src/derive/from.rs b/module/core/derive_tools_meta/src/derive/from.rs index 5bcae1702c..31412b8154 100644 --- a/module/core/derive_tools_meta/src/derive/from.rs +++ b/module/core/derive_tools_meta/src/derive/from.rs @@ -13,7 +13,7 @@ use macro_tools:: AttributePropertyOptionalSingletone, }; -use former_types::ComponentAssign; +use former_types::Assign; // @@ -515,18 +515,30 @@ impl AttributeComponent for ItemAttributeConfig } -impl< IntoT > ComponentAssign< ItemAttributeConfig, IntoT > for ItemAttributes +impl< IntoT > Assign< ItemAttributeConfig, IntoT > for ItemAttributes where IntoT : Into< ItemAttributeConfig >, { #[ inline( always ) ] fn assign( &mut self, component : IntoT ) { - self.config = component.into(); + self.config.assign( component.into() ); + } +} + +impl< IntoT > Assign< ItemAttributeConfig, IntoT > for ItemAttributeConfig +where + IntoT : Into< ItemAttributeConfig >, +{ + #[ inline( always ) ] + fn assign( &mut self, component : IntoT ) + { + let component = component.into(); + self.enabled.assign( component.enabled ); } } -impl< IntoT > ComponentAssign< AttributePropertyEnabled, IntoT > for ItemAttributeConfig +impl< IntoT > Assign< AttributePropertyEnabled, IntoT > for ItemAttributeConfig where IntoT : Into< AttributePropertyEnabled >, { @@ -695,7 +707,7 @@ impl AttributeComponent for FieldAttributeConfig } -impl< IntoT > ComponentAssign< FieldAttributeConfig, IntoT > for FieldAttributes +impl< IntoT > Assign< FieldAttributeConfig, IntoT > for FieldAttributes where IntoT : Into< FieldAttributeConfig >, { @@ -703,13 +715,10 @@ where fn assign( &mut self, component : IntoT ) { self.config.assign( component.into() ); - // let component = component.into(); - // self.config.enabled.assign( component.enabled ); - // self.config.debug.assign( component.debug ); } } -impl< IntoT > ComponentAssign< FieldAttributeConfig, IntoT > for FieldAttributeConfig +impl< IntoT > Assign< FieldAttributeConfig, IntoT > for FieldAttributeConfig where IntoT : Into< FieldAttributeConfig >, { @@ -722,7 +731,7 @@ where } } -impl< IntoT > ComponentAssign< AttributePropertyEnabled, IntoT > for FieldAttributeConfig +impl< IntoT > Assign< AttributePropertyEnabled, IntoT > for FieldAttributeConfig where IntoT : Into< AttributePropertyEnabled >, { @@ -733,7 +742,7 @@ where } } -impl< IntoT > ComponentAssign< AttributePropertyDebug, IntoT > for FieldAttributeConfig +impl< IntoT > Assign< AttributePropertyDebug, IntoT > for FieldAttributeConfig where IntoT : Into< AttributePropertyDebug >, { diff --git a/module/core/former/tests/inc/components_tests/component_assign.rs b/module/core/former/tests/inc/components_tests/component_assign.rs index b2b1fdde8b..546cb3852b 100644 --- a/module/core/former/tests/inc/components_tests/component_assign.rs +++ b/module/core/former/tests/inc/components_tests/component_assign.rs @@ -1,10 +1,10 @@ #[ allow( unused_imports ) ] use super::*; #[ allow( unused_imports ) ] -use former::ComponentAssign; +use former::Assign; -#[ derive( Default, PartialEq, Debug, former::ComponentAssign ) ] +#[ derive( Default, PartialEq, Debug, former::Assign ) ] // #[ debug ] struct Person { diff --git a/module/core/former/tests/inc/components_tests/component_assign_manual.rs b/module/core/former/tests/inc/components_tests/component_assign_manual.rs index d858c5f989..fe1131845a 100644 --- a/module/core/former/tests/inc/components_tests/component_assign_manual.rs +++ b/module/core/former/tests/inc/components_tests/component_assign_manual.rs @@ -1,7 +1,7 @@ #[ allow( unused_imports ) ] use super::*; #[ allow( unused_imports ) ] -use former::ComponentAssign; +use former::Assign; #[ derive( Default, PartialEq, Debug ) ] @@ -11,7 +11,7 @@ struct Person name : String, } -impl< IntoT > ComponentAssign< i32, IntoT > for Person +impl< IntoT > Assign< i32, IntoT > for Person where IntoT : Into< i32 >, { @@ -21,7 +21,7 @@ where } } -impl< IntoT > ComponentAssign< String, IntoT > for Person +impl< IntoT > Assign< String, IntoT > for Person where IntoT : Into< String >, { diff --git a/module/core/former/tests/inc/components_tests/components_assign.rs b/module/core/former/tests/inc/components_tests/components_assign.rs index 84f01db2a8..2867a3cc8b 100644 --- a/module/core/former/tests/inc/components_tests/components_assign.rs +++ b/module/core/former/tests/inc/components_tests/components_assign.rs @@ -1,13 +1,13 @@ #[ allow( unused_imports ) ] use super::*; #[ allow( unused_imports ) ] -use former::{ ComponentAssign, AssignWithType }; +use former::{ Assign, AssignWithType }; /// /// Options1 /// -#[ derive( Debug, Default, PartialEq, the_module::ComponentAssign, the_module::ComponentsAssign ) ] +#[ derive( Debug, Default, PartialEq, the_module::Assign, the_module::ComponentsAssign ) ] pub struct Options1 { field1 : i32, @@ -46,7 +46,7 @@ impl From< &Options1 > for f32 /// Options2 /// -#[ derive( Debug, Default, PartialEq, the_module::ComponentAssign, the_module::ComponentsAssign ) ] +#[ derive( Debug, Default, PartialEq, the_module::Assign, the_module::ComponentsAssign ) ] pub struct Options2 { field1 : i32, diff --git a/module/core/former/tests/inc/components_tests/components_assign_manual.rs b/module/core/former/tests/inc/components_tests/components_assign_manual.rs index 9d7907d05f..bc88f29e14 100644 --- a/module/core/former/tests/inc/components_tests/components_assign_manual.rs +++ b/module/core/former/tests/inc/components_tests/components_assign_manual.rs @@ -1,7 +1,7 @@ #[ allow( unused_imports ) ] use super::*; #[ allow( unused_imports ) ] -use former::{ ComponentAssign, AssignWithType }; +use former::{ Assign, AssignWithType }; /// /// Options1 @@ -42,7 +42,7 @@ impl From< &Options1 > for f32 } } -impl< IntoT > former::ComponentAssign< i32, IntoT > for Options1 +impl< IntoT > former::Assign< i32, IntoT > for Options1 where IntoT : Into< i32 >, { @@ -53,7 +53,7 @@ where } } -impl< IntoT > former::ComponentAssign< String, IntoT > for Options1 +impl< IntoT > former::Assign< String, IntoT > for Options1 where IntoT : Into< String >, { @@ -64,7 +64,7 @@ where } } -impl< IntoT > former::ComponentAssign< f32, IntoT > for Options1 +impl< IntoT > former::Assign< f32, IntoT > for Options1 where IntoT : Into< f32 >, { @@ -93,9 +93,9 @@ where // #[ allow( dead_code ) ] impl< T, IntoT > Options1ComponentsAssign< IntoT > for T where - T : former::ComponentAssign< i32, IntoT >, - T : former::ComponentAssign< String, IntoT >, - T : former::ComponentAssign< f32, IntoT >, + T : former::Assign< i32, IntoT >, + T : former::Assign< String, IntoT >, + T : former::Assign< f32, IntoT >, IntoT : Into< i32 >, IntoT : Into< String >, IntoT : Into< f32 >, @@ -104,9 +104,9 @@ where #[ inline( always ) ] fn options_1_assign( &mut self, component : IntoT ) { - former::ComponentAssign::< i32, _ >::assign( self, component.clone() ); - former::ComponentAssign::< String, _ >::assign( self, component.clone() ); - former::ComponentAssign::< f32, _ >::assign( self, component.clone() ); + former::Assign::< i32, _ >::assign( self, component.clone() ); + former::Assign::< String, _ >::assign( self, component.clone() ); + former::Assign::< f32, _ >::assign( self, component.clone() ); } } @@ -139,7 +139,7 @@ impl From< &Options2 > for String } } -impl< IntoT > former::ComponentAssign< i32, IntoT > for Options2 +impl< IntoT > former::Assign< i32, IntoT > for Options2 where IntoT : Into< i32 >, { @@ -150,7 +150,7 @@ where } } -impl< IntoT > former::ComponentAssign< String, IntoT > for Options2 +impl< IntoT > former::Assign< String, IntoT > for Options2 where IntoT : Into< String >, { @@ -176,8 +176,8 @@ where impl< T, IntoT > Options2ComponentsAssign< IntoT > for T where - T : former::ComponentAssign< i32, IntoT >, - T : former::ComponentAssign< String, IntoT >, + T : former::Assign< i32, IntoT >, + T : former::Assign< String, IntoT >, IntoT : Into< i32 >, IntoT : Into< String >, IntoT : Clone, @@ -185,8 +185,8 @@ where #[ inline( always ) ] fn options_2_assign( &mut self, component : IntoT ) { - former::ComponentAssign::< i32, _ >::assign( self, component.clone() ); - former::ComponentAssign::< String, _ >::assign( self, component.clone() ); + former::Assign::< i32, _ >::assign( self, component.clone() ); + former::Assign::< String, _ >::assign( self, component.clone() ); } } diff --git a/module/core/former/tests/inc/components_tests/composite.rs b/module/core/former/tests/inc/components_tests/composite.rs index 723f3be16c..091fcc268b 100644 --- a/module/core/former/tests/inc/components_tests/composite.rs +++ b/module/core/former/tests/inc/components_tests/composite.rs @@ -1,7 +1,7 @@ #[ allow( unused_imports ) ] use super::*; #[ allow( unused_imports ) ] -use former::{ ComponentAssign, AssignWithType }; +use former::{ Assign, AssignWithType }; /// /// Options1 @@ -14,7 +14,7 @@ use former::{ ComponentAssign, AssignWithType }; Default, PartialEq, the_module::ComponentFrom, - the_module::ComponentAssign, + the_module::Assign, the_module::ComponentsAssign, the_module::FromComponents, ) @@ -38,7 +38,7 @@ pub struct Options1 Default, PartialEq, the_module::ComponentFrom, - the_module::ComponentAssign, + the_module::Assign, the_module::ComponentsAssign, the_module::FromComponents, ) diff --git a/module/core/former/tests/inc/components_tests/composite_manual.rs b/module/core/former/tests/inc/components_tests/composite_manual.rs index 03fc1f28f9..276def66ae 100644 --- a/module/core/former/tests/inc/components_tests/composite_manual.rs +++ b/module/core/former/tests/inc/components_tests/composite_manual.rs @@ -1,7 +1,7 @@ #[ allow( unused_imports ) ] use super::*; #[ allow( unused_imports ) ] -use former::{ ComponentAssign, AssignWithType }; +use former::{ Assign, AssignWithType }; /// /// Options1 @@ -42,7 +42,7 @@ impl From< &Options1 > for f32 } } -impl< IntoT > former::ComponentAssign< i32, IntoT > for Options1 +impl< IntoT > former::Assign< i32, IntoT > for Options1 where IntoT : Into< i32 >, { @@ -53,7 +53,7 @@ where } } -impl< IntoT > former::ComponentAssign< String, IntoT > for Options1 +impl< IntoT > former::Assign< String, IntoT > for Options1 where IntoT : Into< String >, { @@ -64,7 +64,7 @@ where } } -impl< IntoT > former::ComponentAssign< f32, IntoT > for Options1 +impl< IntoT > former::Assign< f32, IntoT > for Options1 where IntoT : Into< f32 >, { @@ -91,9 +91,9 @@ where impl< T, IntoT > Options1ComponentsAssign< IntoT > for T where - T : former::ComponentAssign< i32, IntoT >, - T : former::ComponentAssign< String, IntoT >, - T : former::ComponentAssign< f32, IntoT >, + T : former::Assign< i32, IntoT >, + T : former::Assign< String, IntoT >, + T : former::Assign< f32, IntoT >, IntoT : Into< i32 >, IntoT : Into< String >, IntoT : Into< f32 >, @@ -102,9 +102,9 @@ where #[ inline( always ) ] fn options_1_assign( &mut self, component : IntoT ) { - former::ComponentAssign::< i32, _ >::assign( self, component.clone() ); - former::ComponentAssign::< String, _ >::assign( self, component.clone() ); - former::ComponentAssign::< f32, _ >::assign( self, component.clone() ); + former::Assign::< i32, _ >::assign( self, component.clone() ); + former::Assign::< String, _ >::assign( self, component.clone() ); + former::Assign::< f32, _ >::assign( self, component.clone() ); } } @@ -137,7 +137,7 @@ impl From< &Options2 > for String } } -impl< IntoT > former::ComponentAssign< i32, IntoT > for Options2 +impl< IntoT > former::Assign< i32, IntoT > for Options2 where IntoT : Into< i32 >, { @@ -148,7 +148,7 @@ where } } -impl< IntoT > former::ComponentAssign< String, IntoT > for Options2 +impl< IntoT > former::Assign< String, IntoT > for Options2 where IntoT : Into< String >, { @@ -174,8 +174,8 @@ where impl< T, IntoT > Options2ComponentsAssign< IntoT > for T where - T : former::ComponentAssign< i32, IntoT >, - T : former::ComponentAssign< String, IntoT >, + T : former::Assign< i32, IntoT >, + T : former::Assign< String, IntoT >, IntoT : Into< i32 >, IntoT : Into< String >, IntoT : Clone, @@ -183,8 +183,8 @@ where #[ inline( always ) ] fn options_2_assign( &mut self, component : IntoT ) { - former::ComponentAssign::< i32, _ >::assign( self, component.clone() ); - former::ComponentAssign::< String, _ >::assign( self, component.clone() ); + former::Assign::< i32, _ >::assign( self, component.clone() ); + former::Assign::< String, _ >::assign( self, component.clone() ); } } diff --git a/module/core/former_meta/src/component/component_assign.rs b/module/core/former_meta/src/component/component_assign.rs index a08bf9b696..de12fc7f5f 100644 --- a/module/core/former_meta/src/component/component_assign.rs +++ b/module/core/former_meta/src/component/component_assign.rs @@ -2,7 +2,7 @@ use super::*; use macro_tools::{ attr, diag, Result }; /// -/// Generates implementations of the `ComponentAssign` trait for each field of a struct. +/// Generates implementations of the `Assign` trait for each field of a struct. /// pub fn component_assign( input : proc_macro::TokenStream ) -> Result< proc_macro2::TokenStream > { @@ -24,18 +24,18 @@ pub fn component_assign( input : proc_macro::TokenStream ) -> Result< proc_macro if has_debug { - let about = format!( "derive : ComponentAssign\nstructure : {item_name}" ); + let about = format!( "derive : Assign\nstructure : {item_name}" ); diag::report_print( about, &original_input, &result ); } Ok( result ) } -/// Generates an implementation of the `ComponentAssign` trait for a specific field of a struct. +/// Generates an implementation of the `Assign` trait for a specific field of a struct. /// /// This function creates the trait implementation that enables setting a struct's field value /// with a type that can be converted into the field's type. It dynamically generates code -/// during the macro execution to provide `ComponentAssign` trait implementations for each field +/// during the macro execution to provide `Assign` trait implementations for each field /// of the struct, facilitating an ergonomic API for modifying struct instances. /// /// # Parameters @@ -46,7 +46,7 @@ pub fn component_assign( input : proc_macro::TokenStream ) -> Result< proc_macro /// # Example of generated code /// /// ```rust, ignore -/// impl< IntoT > former::ComponentAssign< i32, IntoT > for Options1 +/// impl< IntoT > former::Assign< i32, IntoT > for Options1 /// where /// IntoT : Into< i32 >, /// { @@ -66,7 +66,7 @@ fn for_each_field( field : &syn::Field, item_name : &syn::Ident ) -> Result< pro Ok( qt! { #[ allow( non_snake_case ) ] - impl< IntoT > ComponentAssign< #field_type, IntoT > for #item_name + impl< IntoT > Assign< #field_type, IntoT > for #item_name where IntoT : Into< #field_type >, { diff --git a/module/core/former_meta/src/component/components_assign.rs b/module/core/former_meta/src/component/components_assign.rs index 9e6b3fdd6c..6b495e7629 100644 --- a/module/core/former_meta/src/component/components_assign.rs +++ b/module/core/former_meta/src/component/components_assign.rs @@ -113,7 +113,7 @@ fn generate_trait_bounds( field_type : &syn::Type ) -> Result< proc_macro2::Toke /// ### Output example /// /// ```ignore -/// T : former::ComponentAssign< i32, IntoT >, +/// T : former::Assign< i32, IntoT >, /// ``` /// fn generate_impl_bounds( field_type : &syn::Type ) -> Result< proc_macro2::TokenStream > @@ -122,7 +122,7 @@ fn generate_impl_bounds( field_type : &syn::Type ) -> Result< proc_macro2::Token ( qt! { - T : former::ComponentAssign< #field_type, IntoT >, + T : former::Assign< #field_type, IntoT >, } ) } @@ -134,7 +134,7 @@ fn generate_impl_bounds( field_type : &syn::Type ) -> Result< proc_macro2::Token /// Output example /// /// ```ignore -/// former::ComponentAssign::< i32, _ >::assign( self.component.clone() ); +/// former::Assign::< i32, _ >::assign( self.component.clone() ); /// ``` /// fn generate_component_assign_call( field : &syn::Field ) -> Result< proc_macro2::TokenStream > @@ -145,7 +145,7 @@ fn generate_component_assign_call( field : &syn::Field ) -> Result< proc_macro2: ( qt! { - former::ComponentAssign::< #field_type, _ >::assign( self, component.clone() ); + former::Assign::< #field_type, _ >::assign( self, component.clone() ); } ) } diff --git a/module/core/former_meta/src/derive_former/field_attrs.rs b/module/core/former_meta/src/derive_former/field_attrs.rs index 4c59182a72..8fd4476c78 100644 --- a/module/core/former_meta/src/derive_former/field_attrs.rs +++ b/module/core/former_meta/src/derive_former/field_attrs.rs @@ -11,7 +11,7 @@ use macro_tools:: AttributePropertyOptionalSyn, AttributePropertyOptionalSingletone, }; -use former_types::{ ComponentAssign }; +use former_types::{ Assign }; /// /// Attributes of a field. @@ -92,6 +92,8 @@ impl FieldAttributes { continue; } + // attributes does not have to be known + // xxx // Match the attribute key and assign to the appropriate field match key_str.as_ref() @@ -151,18 +153,33 @@ impl AttributeComponent for AttributeConfig } -impl< IntoT > ComponentAssign< AttributeConfig, IntoT > for FieldAttributes +impl< IntoT > Assign< AttributeConfig, IntoT > for FieldAttributes where IntoT : Into< AttributeConfig >, { #[ inline( always ) ] fn assign( &mut self, component : IntoT ) { - self.config = Some( component.into() ); + let component : AttributeConfig = component.into(); + component.assign_to_option( &mut self.config ); + // self.config.assign( component.into() ); + // xxx2 : continue } } -impl< IntoT > ComponentAssign< AttributePropertyDefault, IntoT > for AttributeConfig +impl< IntoT > Assign< AttributeConfig, IntoT > for AttributeConfig +where + IntoT : Into< AttributeConfig >, +{ + #[ inline( always ) ] + fn assign( &mut self, component : IntoT ) + { + let component = component.into(); + self.default.assign( component.default ); + } +} + +impl< IntoT > Assign< AttributePropertyDefault, IntoT > for AttributeConfig where IntoT : Into< AttributePropertyDefault >, { @@ -273,7 +290,7 @@ impl AttributeComponent for AttributeScalarSetter } -impl< IntoT > ComponentAssign< AttributeScalarSetter, IntoT > for FieldAttributes +impl< IntoT > Assign< AttributeScalarSetter, IntoT > for FieldAttributes where IntoT : Into< AttributeScalarSetter >, { @@ -284,7 +301,7 @@ where } } -impl< IntoT > ComponentAssign< AttributePropertyName, IntoT > for AttributeScalarSetter +impl< IntoT > Assign< AttributePropertyName, IntoT > for AttributeScalarSetter where IntoT : Into< AttributePropertyName >, { @@ -295,7 +312,7 @@ where } } -impl< IntoT > ComponentAssign< AttributePropertySetter, IntoT > for AttributeScalarSetter +impl< IntoT > Assign< AttributePropertySetter, IntoT > for AttributeScalarSetter where IntoT : Into< AttributePropertySetter >, { @@ -306,7 +323,7 @@ where } } -impl< IntoT > ComponentAssign< AttributePropertyDebug, IntoT > for AttributeScalarSetter +impl< IntoT > Assign< AttributePropertyDebug, IntoT > for AttributeScalarSetter where IntoT : Into< AttributePropertyDebug >, { @@ -433,7 +450,7 @@ impl AttributeComponent for AttributeSubformScalarSetter } -impl< IntoT > ComponentAssign< AttributeSubformScalarSetter, IntoT > for FieldAttributes +impl< IntoT > Assign< AttributeSubformScalarSetter, IntoT > for FieldAttributes where IntoT : Into< AttributeSubformScalarSetter >, { @@ -444,7 +461,7 @@ where } } -impl< IntoT > ComponentAssign< AttributePropertyName, IntoT > for AttributeSubformScalarSetter +impl< IntoT > Assign< AttributePropertyName, IntoT > for AttributeSubformScalarSetter where IntoT : Into< AttributePropertyName >, { @@ -455,7 +472,7 @@ where } } -impl< IntoT > ComponentAssign< AttributePropertySetter, IntoT > for AttributeSubformScalarSetter +impl< IntoT > Assign< AttributePropertySetter, IntoT > for AttributeSubformScalarSetter where IntoT : Into< AttributePropertySetter >, { @@ -466,7 +483,7 @@ where } } -impl< IntoT > ComponentAssign< AttributePropertyDebug, IntoT > for AttributeSubformScalarSetter +impl< IntoT > Assign< AttributePropertyDebug, IntoT > for AttributeSubformScalarSetter where IntoT : Into< AttributePropertyDebug >, { @@ -595,7 +612,7 @@ impl AttributeComponent for AttributeSubformCollectionSetter } -impl< IntoT > ComponentAssign< AttributeSubformCollectionSetter, IntoT > for FieldAttributes +impl< IntoT > Assign< AttributeSubformCollectionSetter, IntoT > for FieldAttributes where IntoT : Into< AttributeSubformCollectionSetter >, { @@ -606,7 +623,7 @@ where } } -impl< IntoT > ComponentAssign< AttributePropertyName, IntoT > for AttributeSubformCollectionSetter +impl< IntoT > Assign< AttributePropertyName, IntoT > for AttributeSubformCollectionSetter where IntoT : Into< AttributePropertyName >, { @@ -617,7 +634,7 @@ where } } -impl< IntoT > ComponentAssign< AttributePropertySetter, IntoT > for AttributeSubformCollectionSetter +impl< IntoT > Assign< AttributePropertySetter, IntoT > for AttributeSubformCollectionSetter where IntoT : Into< AttributePropertySetter >, { @@ -628,7 +645,7 @@ where } } -impl< IntoT > ComponentAssign< AttributePropertyDefinition, IntoT > for AttributeSubformCollectionSetter +impl< IntoT > Assign< AttributePropertyDefinition, IntoT > for AttributeSubformCollectionSetter where IntoT : Into< AttributePropertyDefinition >, { @@ -639,7 +656,7 @@ where } } -impl< IntoT > ComponentAssign< AttributePropertyDebug, IntoT > for AttributeSubformCollectionSetter +impl< IntoT > Assign< AttributePropertyDebug, IntoT > for AttributeSubformCollectionSetter where IntoT : Into< AttributePropertyDebug >, { @@ -775,7 +792,7 @@ impl AttributeComponent for AttributeSubformEntrySetter } -impl< IntoT > ComponentAssign< AttributeSubformEntrySetter, IntoT > for FieldAttributes +impl< IntoT > Assign< AttributeSubformEntrySetter, IntoT > for FieldAttributes where IntoT : Into< AttributeSubformEntrySetter >, { @@ -786,7 +803,7 @@ where } } -impl< IntoT > ComponentAssign< AttributePropertyName, IntoT > for AttributeSubformEntrySetter +impl< IntoT > Assign< AttributePropertyName, IntoT > for AttributeSubformEntrySetter where IntoT : Into< AttributePropertyName >, { @@ -797,7 +814,7 @@ where } } -impl< IntoT > ComponentAssign< AttributePropertySetter, IntoT > for AttributeSubformEntrySetter +impl< IntoT > Assign< AttributePropertySetter, IntoT > for AttributeSubformEntrySetter where IntoT : Into< AttributePropertySetter >, { @@ -808,7 +825,7 @@ where } } -impl< IntoT > ComponentAssign< AttributePropertyDebug, IntoT > for AttributeSubformEntrySetter +impl< IntoT > Assign< AttributePropertyDebug, IntoT > for AttributeSubformEntrySetter where IntoT : Into< AttributePropertyDebug >, { diff --git a/module/core/former_meta/src/derive_former/struct_attrs.rs b/module/core/former_meta/src/derive_former/struct_attrs.rs index 211b9abfc9..f88ca65a71 100644 --- a/module/core/former_meta/src/derive_former/struct_attrs.rs +++ b/module/core/former_meta/src/derive_former/struct_attrs.rs @@ -13,7 +13,7 @@ use macro_tools:: AttributePropertyOptionalSingletone, }; -use former_types::{ ComponentAssign }; +use former_types::{ Assign }; /// Represents the attributes of a struct, including storage fields, mutator, and perform attributes. @@ -198,7 +198,7 @@ impl AttributeComponent for AttributeStorageFields } -impl< IntoT > ComponentAssign< AttributeStorageFields, IntoT > for ItemAttributes +impl< IntoT > Assign< AttributeStorageFields, IntoT > for ItemAttributes where IntoT : Into< AttributeStorageFields >, { @@ -268,7 +268,7 @@ impl AttributeComponent for AttributeMutator } -impl< IntoT > ComponentAssign< AttributeMutator, IntoT > for ItemAttributes +impl< IntoT > Assign< AttributeMutator, IntoT > for ItemAttributes where IntoT : Into< AttributeMutator >, { @@ -279,7 +279,7 @@ where } } -impl< IntoT > ComponentAssign< AttributePropertyDebug, IntoT > for AttributeMutator +impl< IntoT > Assign< AttributePropertyDebug, IntoT > for AttributeMutator where IntoT : Into< AttributePropertyDebug >, { @@ -290,7 +290,7 @@ where } } -impl< IntoT > ComponentAssign< AttributePropertyCustom, IntoT > for AttributeMutator +impl< IntoT > Assign< AttributePropertyCustom, IntoT > for AttributeMutator where IntoT : Into< AttributePropertyCustom >, { @@ -399,7 +399,7 @@ impl syn::parse::Parse for AttributePerform } } -impl< IntoT > ComponentAssign< AttributePerform, IntoT > for ItemAttributes +impl< IntoT > Assign< AttributePerform, IntoT > for ItemAttributes where IntoT : Into< AttributePerform >, { diff --git a/module/core/former_meta/src/lib.rs b/module/core/former_meta/src/lib.rs index e9d2e50279..3a4d6af4d0 100644 --- a/module/core/former_meta/src/lib.rs +++ b/module/core/former_meta/src/lib.rs @@ -170,10 +170,10 @@ pub fn component_from( input : proc_macro::TokenStream ) -> proc_macro::TokenStr } } -/// Derives the `ComponentAssign` trait for struct fields, allowing each field to be set +/// Derives the `Assign` trait for struct fields, allowing each field to be set /// with a value that can be converted into the field's type. /// -/// This macro facilitates the automatic implementation of the `ComponentAssign` trait for all +/// This macro facilitates the automatic implementation of the `Assign` trait for all /// fields within a struct, leveraging the power of Rust's type system to ensure type safety /// and conversion logic. It is particularly useful for builder patterns or mutating instances /// of data structures in a fluent and ergonomic manner. @@ -188,12 +188,12 @@ pub fn component_from( input : proc_macro::TokenStream ) -> proc_macro::TokenStr /// /// # Input Code Example /// -/// Given a struct definition annotated with `#[ derive( ComponentAssign ) ]` : +/// Given a struct definition annotated with `#[ derive( Assign ) ]` : /// /// ```rust -/// use former::ComponentAssign; +/// use former::Assign; /// -/// #[ derive( Default, PartialEq, Debug, former::ComponentAssign ) ] +/// #[ derive( Default, PartialEq, Debug, former::Assign ) ] /// struct Person /// { /// age : i32, @@ -211,7 +211,7 @@ pub fn component_from( input : proc_macro::TokenStream ) -> proc_macro::TokenStr /// The procedural macro generates the following implementations for `Person` : /// /// ```rust -/// use former::ComponentAssign; +/// use former::Assign; /// /// #[ derive( Default, PartialEq, Debug ) ] /// struct Person @@ -220,7 +220,7 @@ pub fn component_from( input : proc_macro::TokenStream ) -> proc_macro::TokenStr /// name : String, /// } /// -/// impl< IntoT > ComponentAssign< i32, IntoT > for Person +/// impl< IntoT > Assign< i32, IntoT > for Person /// where /// IntoT : Into< i32 >, /// { @@ -230,7 +230,7 @@ pub fn component_from( input : proc_macro::TokenStream ) -> proc_macro::TokenStr /// } /// } /// -/// impl< IntoT > ComponentAssign< String, IntoT > for Person +/// impl< IntoT > Assign< String, IntoT > for Person /// where /// IntoT : Into< String >, /// { @@ -250,7 +250,7 @@ pub fn component_from( input : proc_macro::TokenStream ) -> proc_macro::TokenStr #[ cfg( feature = "enabled" ) ] #[ cfg( feature = "derive_component_assign" ) ] -#[ proc_macro_derive( ComponentAssign, attributes( debug ) ) ] +#[ proc_macro_derive( Assign, attributes( debug ) ) ] pub fn component_assign( input : proc_macro::TokenStream ) -> proc_macro::TokenStream { let result = component::component_assign::component_assign( input ); @@ -274,7 +274,7 @@ pub fn component_assign( input : proc_macro::TokenStream ) -> proc_macro::TokenS /// # Conditions /// /// - This macro is only enabled when the `derive_components_assign` feature is active in your `Cargo.toml`. -/// - The type must implement `ComponentAssign` (`derive( ComponentAssign )`) +/// - The type must implement `Assign` (`derive( Assign )`) /// /// # Limitations /// This trait cannot be derived, if the struct has fields with identical types @@ -284,9 +284,9 @@ pub fn component_assign( input : proc_macro::TokenStream ) -> proc_macro::TokenS /// An example when we encapsulate parameters passed to a function in a struct. /// /// ```rust -/// use former::{ ComponentAssign, ComponentsAssign }; +/// use former::{ Assign, ComponentsAssign }; /// -/// #[ derive( Default, ComponentAssign, ComponentsAssign ) ] +/// #[ derive( Default, Assign, ComponentsAssign ) ] /// struct BigOpts /// { /// cond : bool, @@ -294,7 +294,7 @@ pub fn component_assign( input : proc_macro::TokenStream ) -> proc_macro::TokenS /// str : String, /// } /// -/// #[ derive( Default, ComponentAssign, ComponentsAssign ) ] +/// #[ derive( Default, Assign, ComponentsAssign ) ] /// struct SmallerOpts /// { /// cond: bool, @@ -343,7 +343,7 @@ pub fn component_assign( input : proc_macro::TokenStream ) -> proc_macro::TokenS /// Which expands approximately into : /// /// ```rust -/// use former::{ ComponentAssign, ComponentsAssign }; +/// use former::{ Assign, ComponentsAssign }; /// /// #[derive(Default)] /// struct BigOpts @@ -353,7 +353,7 @@ pub fn component_assign( input : proc_macro::TokenStream ) -> proc_macro::TokenS /// str : String, /// } /// -/// impl< IntoT > ComponentAssign< bool, IntoT > for BigOpts +/// impl< IntoT > Assign< bool, IntoT > for BigOpts /// where /// IntoT : Into< bool >, /// { @@ -363,7 +363,7 @@ pub fn component_assign( input : proc_macro::TokenStream ) -> proc_macro::TokenS /// } /// } /// -/// impl< IntoT > ComponentAssign< i32, IntoT > for BigOpts +/// impl< IntoT > Assign< i32, IntoT > for BigOpts /// where /// IntoT : Into< i32 >, /// { @@ -373,7 +373,7 @@ pub fn component_assign( input : proc_macro::TokenStream ) -> proc_macro::TokenS /// } /// } /// -/// impl< IntoT > ComponentAssign< String, IntoT > for BigOpts +/// impl< IntoT > Assign< String, IntoT > for BigOpts /// where /// IntoT : Into< String >, /// { @@ -395,9 +395,9 @@ pub fn component_assign( input : proc_macro::TokenStream ) -> proc_macro::TokenS /// /// impl< T, IntoT > BigOptsComponentsAssign< IntoT > for T /// where -/// T : former::ComponentAssign< bool, IntoT >, -/// T : former::ComponentAssign< i32, IntoT >, -/// T : former::ComponentAssign< String, IntoT >, +/// T : former::Assign< bool, IntoT >, +/// T : former::Assign< i32, IntoT >, +/// T : former::Assign< String, IntoT >, /// IntoT : Into< bool >, /// IntoT : Into< i32 >, /// IntoT : Into< String >, @@ -405,9 +405,9 @@ pub fn component_assign( input : proc_macro::TokenStream ) -> proc_macro::TokenS /// { /// fn components_assign( &mut self, component : IntoT ) /// { -/// former::ComponentAssign::< bool, _ >::assign( self, component.clone() ); -/// former::ComponentAssign::< i32, _ >::assign( self, component.clone() ); -/// former::ComponentAssign::< String, _ >::assign( self, component.clone() ); +/// former::Assign::< bool, _ >::assign( self, component.clone() ); +/// former::Assign::< i32, _ >::assign( self, component.clone() ); +/// former::Assign::< String, _ >::assign( self, component.clone() ); /// } /// } /// @@ -418,7 +418,7 @@ pub fn component_assign( input : proc_macro::TokenStream ) -> proc_macro::TokenS /// int : i32, /// } /// -/// impl< IntoT > ComponentAssign< bool, IntoT > for SmallerOpts +/// impl< IntoT > Assign< bool, IntoT > for SmallerOpts /// where /// IntoT : Into< bool >, /// { @@ -428,7 +428,7 @@ pub fn component_assign( input : proc_macro::TokenStream ) -> proc_macro::TokenS /// } /// } /// -/// impl< IntoT > ComponentAssign< i32, IntoT > for SmallerOpts +/// impl< IntoT > Assign< i32, IntoT > for SmallerOpts /// where /// IntoT : Into< i32 >, /// { @@ -449,16 +449,16 @@ pub fn component_assign( input : proc_macro::TokenStream ) -> proc_macro::TokenS /// /// impl< T, IntoT > SmallerOptsComponentsAssign< IntoT > for T /// where -/// T : former::ComponentAssign< bool, IntoT >, -/// T : former::ComponentAssign< i32, IntoT >, +/// T : former::Assign< bool, IntoT >, +/// T : former::Assign< i32, IntoT >, /// IntoT : Into< bool >, /// IntoT : Into< i32 >, /// IntoT : Clone, /// { /// fn smaller_opts_assign( &mut self, component : IntoT ) /// { -/// former::ComponentAssign::< bool, _ >::assign( self, component.clone() ); -/// former::ComponentAssign::< i32, _ >::assign( self, component.clone() ); +/// former::Assign::< bool, _ >::assign( self, component.clone() ); +/// former::Assign::< i32, _ >::assign( self, component.clone() ); /// } /// } /// diff --git a/module/core/former_types/Readme.md b/module/core/former_types/Readme.md index 105cb237a2..42346b3bc0 100644 --- a/module/core/former_types/Readme.md +++ b/module/core/former_types/Readme.md @@ -8,12 +8,12 @@ A flexible and extensible implementation of the builder pattern. Its compile-time structures and traits that are not generated but reused. -## Example: Using Trait ComponentAssign +## Example: Using Trait Assign Demonstrates setting various components (fields) of a struct. The `former_types` crate provides a generic interface for setting components on an object. This example defines a `Person` struct -and implements the `ComponentAssign` trait for its fields. It shows how to use these implementations to set the fields of a `Person` +and implements the `Assign` trait for its fields. It shows how to use these implementations to set the fields of a `Person` instance using different types that can be converted into the required types. ```rust @@ -23,7 +23,7 @@ fn main() {} #[ cfg( all( feature = "derive_former", feature = "enabled" ) ) ] fn main() { - use former_types::ComponentAssign; + use former_types::Assign; #[ derive( Default, PartialEq, Debug ) ] struct Person @@ -32,7 +32,7 @@ fn main() name : String, } - impl< IntoT > ComponentAssign< i32, IntoT > for Person + impl< IntoT > Assign< i32, IntoT > for Person where IntoT : Into< i32 >, { @@ -42,7 +42,7 @@ fn main() } } - impl< IntoT > ComponentAssign< String, IntoT > for Person + impl< IntoT > Assign< String, IntoT > for Person where IntoT : Into< String >, { diff --git a/module/core/former_types/examples/former_types_trivial.rs b/module/core/former_types/examples/former_types_trivial.rs index 70d226686d..c379293640 100644 --- a/module/core/former_types/examples/former_types_trivial.rs +++ b/module/core/former_types/examples/former_types_trivial.rs @@ -1,17 +1,17 @@ //! -//! ## Example: Using Trait ComponentAssign +//! ## Example: Using Trait Assign //! //! Demonstrates setting various components (fields) of a struct. //! //! The `former_types` crate provides a generic interface for setting components on an object. This example defines a `Person` struct -//! and implements the `ComponentAssign` trait for its fields. It shows how to use these implementations to set the fields of a `Person` +//! and implements the `Assign` trait for its fields. It shows how to use these implementations to set the fields of a `Person` //! instance using different types that can be converted into the required types. //! //! ## Explanation //! //! - **Person Struct**: The `Person` struct has two fields: `age` (an integer) and `name` (a string). The `Default` and `PartialEq` traits are derived to facilitate default construction and comparison. //! -//! - **ComponentAssign Implementations**: The `ComponentAssign` trait is implemented for the `age` and `name` fields of the `Person` struct. +//! - **Assign Implementations**: The `Assign` trait is implemented for the `age` and `name` fields of the `Person` struct. //! - For `age`: The trait is implemented for any type that can be converted into an `i32`. //! - For `name`: The trait is implemented for any type that can be converted into a `String`. //! @@ -26,7 +26,7 @@ fn main() {} #[ cfg( all( feature = "derive_former", feature = "enabled" ) ) ] fn main() { - use former_types::ComponentAssign; + use former_types::Assign; #[ derive( Default, PartialEq, Debug ) ] struct Person @@ -35,7 +35,7 @@ fn main() name : String, } - impl< IntoT > ComponentAssign< i32, IntoT > for Person + impl< IntoT > Assign< i32, IntoT > for Person where IntoT : Into< i32 >, { @@ -45,7 +45,7 @@ fn main() } } - impl< IntoT > ComponentAssign< String, IntoT > for Person + impl< IntoT > Assign< String, IntoT > for Person where IntoT : Into< String >, { diff --git a/module/core/former_types/src/component.rs b/module/core/former_types/src/component.rs index 68a5479fce..2d541ee736 100644 --- a/module/core/former_types/src/component.rs +++ b/module/core/former_types/src/component.rs @@ -17,17 +17,17 @@ /// /// # Examples /// -/// Implementing `ComponentAssign` to set a name string on a struct : +/// Implementing `Assign` to set a name string on a struct : /// /// ```rust -/// use former_types::ComponentAssign; // use crate `former` instead of crate `former_types` unless you need to use crate `former_types` directly +/// use former_types::Assign; // use crate `former` instead of crate `former_types` unless you need to use crate `former_types` directly /// /// struct MyStruct /// { /// name : String, /// } /// -/// impl< IntoT : Into< String > > ComponentAssign< String, IntoT > for MyStruct +/// impl< IntoT : Into< String > > Assign< String, IntoT > for MyStruct /// { /// fn assign( &mut self, component : IntoT ) /// { @@ -40,7 +40,7 @@ /// assert_eq!( obj.name, "New Name" ); /// ``` #[ cfg( any( feature = "types_component_assign" ) ) ] -pub trait ComponentAssign< T, IntoT > +pub trait Assign< T, IntoT > where IntoT : Into< T >, { @@ -49,6 +49,19 @@ where /// This method takes ownership of the given value ( `component` ), which is of type `IntoT`. /// `component` is then converted into type `T` and set as the component of the object. fn assign( &mut self, component : IntoT ); + + #[ inline( always ) ] + fn assign_to_option< IntoSelf >( self, dst : &mut Option< Self > ) + where + Self : Sized + Assign< Self, Self >, + { + match dst + { + Some( val ) => Assign::assign( val, self ), + None => *dst = Some( self ), + } + } + } /// The `AssignWithType` trait provides a mechanism to set a component on an object, utilizing the type information explicitly. This trait extends the functionality of `SetComponen`t by allowing implementers to specify the component's type at the method call site, enhancing expressiveness in code that manipulates object states. @@ -67,14 +80,14 @@ where /// ### Example /// /// ```rust -/// use former_types::{ ComponentAssign, AssignWithType }; // use crate `former` instead of crate `former_types` unless you need to use crate `former_types` directly +/// use former_types::{ Assign, AssignWithType }; // use crate `former` instead of crate `former_types` unless you need to use crate `former_types` directly /// /// struct UserProfile /// { /// username : String, /// } /// -/// impl< IntoT : Into< String > > ComponentAssign< String, IntoT > for UserProfile +/// impl< IntoT : Into< String > > Assign< String, IntoT > for UserProfile // where String: From< String >, /// { /// fn assign( &mut self, component : IntoT ) @@ -97,7 +110,7 @@ pub trait AssignWithType fn assign_with_type< T, IntoT >( &mut self, component : IntoT ) where IntoT : Into< T >, - Self : ComponentAssign< T, IntoT >; + Self : Assign< T, IntoT >; } #[ cfg( any( feature = "types_component_assign" ) ) ] @@ -108,9 +121,9 @@ impl< S > AssignWithType for S fn assign_with_type< T, IntoT >( &mut self, component : IntoT ) where IntoT : Into< T >, - Self : ComponentAssign< T, IntoT >, + Self : Assign< T, IntoT >, { - ComponentAssign::< T, IntoT >::assign( self, component ); + Assign::< T, IntoT >::assign( self, component ); } } diff --git a/module/core/macro_tools/Readme.md b/module/core/macro_tools/Readme.md index b45e890e93..039313e81f 100644 --- a/module/core/macro_tools/Readme.md +++ b/module/core/macro_tools/Readme.md @@ -58,7 +58,7 @@ This example demonstrates an approach to parsing attributes and their properties The attributes are collected into a struct that aggregates them, and attribute properties are parsed using reusable components from a library. The example shows how to use `AttributePropertyBoolean` for parsing boolean properties and the roles of the traits -`AttributePropertyComponent` and `AttributeComponent`. The `ComponentAssign` trait is +`AttributePropertyComponent` and `AttributeComponent`. The `Assign` trait is also used to simplify the logic of assigning fields. Attributes are collected into a `ItemAttributes` struct, and attribute properties are parsed @@ -66,7 +66,7 @@ using reusable components like `AttributePropertyBoolean`. - `AttributeComponent`: A trait that defines how an attribute should be parsed from a `syn::Attribute`. - `AttributePropertyComponent`: A trait that defines a marker for attribute properties. -- `ComponentAssign`: A trait that simplifies the logic of assigning fields to a struct. Using a +- `Assign`: A trait that simplifies the logic of assigning fields to a struct. Using a component-based approach requires each field to have a unique type, which aligns with the strengths of strongly-typed languages. This method ensures that the logic of assigning values to fields is encapsulated within the fields themselves, promoting modularity @@ -98,7 +98,7 @@ fn main() AttributePropertyBoolean, AttributePropertySingletone, }; - use former_types::ComponentAssign; + use former_types::Assign; /// Represents the attributes of a struct. Aggregates all its attributes. #[ derive( Debug, Default ) ] @@ -201,8 +201,8 @@ fn main() } } - // Implement `ComponentAssign` trait to allow assigning `AttributeMutator` to `ItemAttributes`. - impl< IntoT > ComponentAssign< AttributeMutator, IntoT > for ItemAttributes + // Implement `Assign` trait to allow assigning `AttributeMutator` to `ItemAttributes`. + impl< IntoT > Assign< AttributeMutator, IntoT > for ItemAttributes where IntoT : Into< AttributeMutator >, { @@ -213,8 +213,8 @@ fn main() } } - // Implement `ComponentAssign` trait to allow assigning `AttributePropertyDebug` to `AttributeMutator`. - impl< IntoT > ComponentAssign< AttributePropertyDebug, IntoT > for AttributeMutator + // Implement `Assign` trait to allow assigning `AttributePropertyDebug` to `AttributeMutator`. + impl< IntoT > Assign< AttributePropertyDebug, IntoT > for AttributeMutator where IntoT : Into< AttributePropertyDebug >, { @@ -225,8 +225,8 @@ fn main() } } - // Implement `ComponentAssign` trait to allow assigning `AttributePropertyCustom` to `AttributeMutator`. - impl< IntoT > ComponentAssign< AttributePropertyCustom, IntoT > for AttributeMutator + // Implement `Assign` trait to allow assigning `AttributePropertyCustom` to `AttributeMutator`. + impl< IntoT > Assign< AttributePropertyCustom, IntoT > for AttributeMutator where IntoT : Into< AttributePropertyCustom >, { diff --git a/module/core/macro_tools/examples/macro_tools_attr_prop.rs b/module/core/macro_tools/examples/macro_tools_attr_prop.rs index 8b4a6639e4..20c8df5c48 100644 --- a/module/core/macro_tools/examples/macro_tools_attr_prop.rs +++ b/module/core/macro_tools/examples/macro_tools_attr_prop.rs @@ -5,7 +5,7 @@ //! The attributes are collected into a struct that aggregates them, and attribute properties //! are parsed using reusable components from a library. The example shows how to use //! `AttributePropertyBoolean` for parsing boolean properties and the roles of the traits -//! `AttributePropertyComponent` and `AttributeComponent`. The `ComponentAssign` trait is +//! `AttributePropertyComponent` and `AttributeComponent`. The `Assign` trait is //! also used to simplify the logic of assigning fields. //! //! Attributes are collected into a `ItemAttributes` struct, and attribute properties are parsed @@ -13,7 +13,7 @@ //! //! - `AttributeComponent`: A trait that defines how an attribute should be parsed from a `syn::Attribute`. //! - `AttributePropertyComponent`: A trait that defines a marker for attribute properties. -//! - `ComponentAssign`: A trait that simplifies the logic of assigning fields to a struct. Using a +//! - `Assign`: A trait that simplifies the logic of assigning fields to a struct. Using a //! component-based approach requires each field to have a unique type, which aligns with the //! strengths of strongly-typed languages. This method ensures that the logic of //! assigning values to fields is encapsulated within the fields themselves, promoting modularity @@ -44,7 +44,7 @@ fn main() AttributePropertyBoolean, AttributePropertySingletone, }; - use former_types::ComponentAssign; + use former_types::Assign; /// Represents the attributes of a struct. Aggregates all its attributes. #[ derive( Debug, Default ) ] @@ -147,8 +147,8 @@ fn main() } } - // Implement `ComponentAssign` trait to allow assigning `AttributeMutator` to `ItemAttributes`. - impl< IntoT > ComponentAssign< AttributeMutator, IntoT > for ItemAttributes + // Implement `Assign` trait to allow assigning `AttributeMutator` to `ItemAttributes`. + impl< IntoT > Assign< AttributeMutator, IntoT > for ItemAttributes where IntoT : Into< AttributeMutator >, { @@ -159,8 +159,8 @@ fn main() } } - // Implement `ComponentAssign` trait to allow assigning `AttributePropertyDebug` to `AttributeMutator`. - impl< IntoT > ComponentAssign< AttributePropertyDebug, IntoT > for AttributeMutator + // Implement `Assign` trait to allow assigning `AttributePropertyDebug` to `AttributeMutator`. + impl< IntoT > Assign< AttributePropertyDebug, IntoT > for AttributeMutator where IntoT : Into< AttributePropertyDebug >, { @@ -171,8 +171,8 @@ fn main() } } - // Implement `ComponentAssign` trait to allow assigning `AttributePropertyCustom` to `AttributeMutator`. - impl< IntoT > ComponentAssign< AttributePropertyCustom, IntoT > for AttributeMutator + // Implement `Assign` trait to allow assigning `AttributePropertyCustom` to `AttributeMutator`. + impl< IntoT > Assign< AttributePropertyCustom, IntoT > for AttributeMutator where IntoT : Into< AttributePropertyCustom >, { diff --git a/module/core/macro_tools/src/attr_prop/boolean.rs b/module/core/macro_tools/src/attr_prop/boolean.rs index 7aa4aeb90f..d4d1220d7f 100644 --- a/module/core/macro_tools/src/attr_prop/boolean.rs +++ b/module/core/macro_tools/src/attr_prop/boolean.rs @@ -4,7 +4,7 @@ //! use crate::*; -use former_types::ComponentAssign; +use former_types::Assign; /// A generic boolean attribute property. /// Defaults to `false`. @@ -125,7 +125,7 @@ impl< Marker > AttributePropertyBoolean< Marker > // xxx : introduce default markers for all properties -impl< Marker, IntoT > ComponentAssign< AttributePropertyBoolean< Marker >, IntoT > +impl< Marker, IntoT > Assign< AttributePropertyBoolean< Marker >, IntoT > for AttributePropertyBoolean< Marker > where IntoT : Into< AttributePropertyBoolean< Marker > >, diff --git a/module/core/macro_tools/src/attr_prop/boolean_optional.rs b/module/core/macro_tools/src/attr_prop/boolean_optional.rs index 3c288d8c97..070d0b6476 100644 --- a/module/core/macro_tools/src/attr_prop/boolean_optional.rs +++ b/module/core/macro_tools/src/attr_prop/boolean_optional.rs @@ -4,7 +4,7 @@ //! use crate::*; -use former_types::ComponentAssign; +use former_types::Assign; /// A generic optional boolean attribute property: `Option< bool >`. /// Defaults to `false`. @@ -29,7 +29,7 @@ impl< Marker > AttributePropertyOptionalBoolean< Marker > } -impl< Marker, IntoT > ComponentAssign< AttributePropertyOptionalBoolean< Marker >, IntoT > +impl< Marker, IntoT > Assign< AttributePropertyOptionalBoolean< Marker >, IntoT > for AttributePropertyOptionalBoolean< Marker > where IntoT : Into< AttributePropertyOptionalBoolean< Marker > >, diff --git a/module/core/macro_tools/src/attr_prop/singletone.rs b/module/core/macro_tools/src/attr_prop/singletone.rs index 1afa7aa52f..1d55d9ac7c 100644 --- a/module/core/macro_tools/src/attr_prop/singletone.rs +++ b/module/core/macro_tools/src/attr_prop/singletone.rs @@ -12,7 +12,7 @@ //! This is useful for attributes that need to enable or disable features or flags. use crate::*; -use former_types::ComponentAssign; +use former_types::Assign; /// Default marker for `AttributePropertySingletone`. /// Used if no marker is defined as parameter. @@ -50,7 +50,7 @@ impl< Marker > AttributePropertySingletone< Marker > } -impl< Marker, IntoT > ComponentAssign< AttributePropertySingletone< Marker >, IntoT > +impl< Marker, IntoT > Assign< AttributePropertySingletone< Marker >, IntoT > for AttributePropertySingletone< Marker > where IntoT : Into< AttributePropertySingletone< Marker > >, diff --git a/module/core/macro_tools/src/attr_prop/singletone_optional.rs b/module/core/macro_tools/src/attr_prop/singletone_optional.rs index b99a71b2c4..6c2b7a5452 100644 --- a/module/core/macro_tools/src/attr_prop/singletone_optional.rs +++ b/module/core/macro_tools/src/attr_prop/singletone_optional.rs @@ -14,7 +14,7 @@ //! This is useful for attributes that need to enable or disable features or flags. use crate::*; -use former_types::ComponentAssign; +use former_types::Assign; /// Default marker for `AttributePropertyOptionalSingletone`. /// Used if no marker is defined as parameter. @@ -65,7 +65,7 @@ impl< Marker > AttributePropertyOptionalSingletone< Marker > } -impl< Marker, IntoT > ComponentAssign< AttributePropertyOptionalSingletone< Marker >, IntoT > +impl< Marker, IntoT > Assign< AttributePropertyOptionalSingletone< Marker >, IntoT > for AttributePropertyOptionalSingletone< Marker > where IntoT : Into< AttributePropertyOptionalSingletone< Marker > >, diff --git a/module/core/macro_tools/src/attr_prop/syn.rs b/module/core/macro_tools/src/attr_prop/syn.rs index 1fc1912532..4b265dde97 100644 --- a/module/core/macro_tools/src/attr_prop/syn.rs +++ b/module/core/macro_tools/src/attr_prop/syn.rs @@ -3,7 +3,7 @@ //! use crate::*; -use former_types::ComponentAssign; +use former_types::Assign; /// /// Property of an attribute which simply wraps one of the standard `syn` types. @@ -35,7 +35,7 @@ where } } -impl< T, Marker, IntoT > ComponentAssign< AttributePropertySyn< T, Marker >, IntoT > +impl< T, Marker, IntoT > Assign< AttributePropertySyn< T, Marker >, IntoT > for AttributePropertySyn< T, Marker > where T : syn::parse::Parse + quote::ToTokens, diff --git a/module/core/macro_tools/src/attr_prop/syn_optional.rs b/module/core/macro_tools/src/attr_prop/syn_optional.rs index e6e2e723c6..2d1bcd3b96 100644 --- a/module/core/macro_tools/src/attr_prop/syn_optional.rs +++ b/module/core/macro_tools/src/attr_prop/syn_optional.rs @@ -3,7 +3,7 @@ //! use crate::*; -use former_types::ComponentAssign; +use former_types::Assign; /// /// Property of an attribute which simply wraps one of the standard `syn` types and keeps it optional. @@ -33,7 +33,7 @@ where } } -impl< T, Marker, IntoT > ComponentAssign< AttributePropertyOptionalSyn< T, Marker >, IntoT > +impl< T, Marker, IntoT > Assign< AttributePropertyOptionalSyn< T, Marker >, IntoT > for AttributePropertyOptionalSyn< T, Marker > where T : syn::parse::Parse + quote::ToTokens, From c4a00f047b0333901d6ea2e0938faffe3cb02ae1 Mon Sep 17 00:00:00 2001 From: wandalen Date: Thu, 30 May 2024 15:51:02 +0300 Subject: [PATCH 33/59] derive_tools, former: implementing ComponentAssign for all attributes --- .../src/derive_former/field_attrs.rs | 6 +- module/core/former_types/src/component.rs | 139 +++++++++++++----- 2 files changed, 106 insertions(+), 39 deletions(-) diff --git a/module/core/former_meta/src/derive_former/field_attrs.rs b/module/core/former_meta/src/derive_former/field_attrs.rs index 8fd4476c78..2cb01981ec 100644 --- a/module/core/former_meta/src/derive_former/field_attrs.rs +++ b/module/core/former_meta/src/derive_former/field_attrs.rs @@ -11,7 +11,7 @@ use macro_tools:: AttributePropertyOptionalSyn, AttributePropertyOptionalSingletone, }; -use former_types::{ Assign }; +use former_types::{ Assign, OptionExt }; /// /// Attributes of a field. @@ -161,9 +161,7 @@ where fn assign( &mut self, component : IntoT ) { let component : AttributeConfig = component.into(); - component.assign_to_option( &mut self.config ); - // self.config.assign( component.into() ); - // xxx2 : continue + self.config.option_assign( component ); } } diff --git a/module/core/former_types/src/component.rs b/module/core/former_types/src/component.rs index 2d541ee736..21398497d8 100644 --- a/module/core/former_types/src/component.rs +++ b/module/core/former_types/src/component.rs @@ -1,30 +1,28 @@ - /// Provides a generic interface for setting a component of a certain type on an object. /// /// This trait abstracts the action of setting or replacing a component, where a component /// can be any part or attribute of an object, such as a field value. It is designed to be -/// generic over the type of the component being set ( `T` ) and the type that can be converted -/// into the component ( `IntoT` ). This design allows for flexible implementations that can +/// generic over the type of the component being set (`T`) and the type that can be converted +/// into the component (`IntoT`). This design allows for flexible implementations that can /// accept various types that can then be converted into the required component type. /// /// # Type Parameters /// -/// - `T` : The type of the component to be set on the implementing object. This type represents +/// - `T`: The type of the component to be set on the implementing object. This type represents /// the final form of the component as it should be stored or represented in the object. -/// - `IntoT` : The type that can be converted into `T`. This allows the `set` method to accept +/// - `IntoT`: The type that can be converted into `T`. This allows the `assign` method to accept /// different types that are capable of being transformed into the required component type `T`, /// providing greater flexibility in setting the component. /// /// # Examples /// -/// Implementing `Assign` to set a name string on a struct : +/// Implementing `Assign` to set a name string on a struct: /// /// ```rust /// use former_types::Assign; // use crate `former` instead of crate `former_types` unless you need to use crate `former_types` directly /// -/// struct MyStruct -/// { -/// name : String, +/// struct MyStruct { +/// name: String, /// } /// /// impl< IntoT : Into< String > > Assign< String, IntoT > for MyStruct @@ -46,38 +44,100 @@ where { /// Sets or replaces the component on the object with the given value. /// - /// This method takes ownership of the given value ( `component` ), which is of type `IntoT`. + /// This method takes ownership of the given value (`component`), which is of type `IntoT`. /// `component` is then converted into type `T` and set as the component of the object. fn assign( &mut self, component : IntoT ); +} + +/// Extension trait to provide a method for setting a component on an `Option` +/// if the `Option` is currently `None`. If the `Option` is `Some`, the method will +/// delegate to the `Assign` trait's `assign` method. +/// +/// # Type Parameters +/// +/// - `T`: The type of the component to be set on the implementing object. This type represents +/// the final form of the component as it should be stored or represented in the object. +/// +/// # Examples +/// +/// Using `option_assign` to set a component on an `Option`: +/// +/// ```rust +/// use former_types::{ Assign, OptionExt }; // use crate `former` instead of crate `former_types` unless you need to use crate `former_types` directly +/// +/// struct MyStruct +/// { +/// name : String, +/// } +/// +/// impl< IntoT : Into< MyStruct > > Assign< MyStruct, IntoT > for MyStruct +/// { +/// fn assign( &mut self, component : IntoT ) +/// { +/// self.name = component.into().name; +/// } +/// } +/// +/// let mut opt_struct: Option< MyStruct > = None; +/// opt_struct.option_assign( MyStruct { name: "New Name".to_string() } ); +/// assert_eq!( opt_struct.unwrap().name, "New Name" ); +/// ``` +#[ cfg( any( feature = "types_component_assign" ) ) ] +pub trait OptionExt< T > : sealed::Sealed +where + T : Sized + Assign< T, T >, +{ + /// Sets the component on the `Option` if it is `None`. + /// + /// If the `Option` is `Some`, the `assign` method is called to update the existing value. + /// + /// # Parameters + /// + /// - `src`: The value to assign to the `Option`. + fn option_assign( & mut self, src : T ); +} +#[ cfg( any( feature = "types_component_assign" ) ) ] +impl< T > OptionExt< T > for Option< T > +where + T : Sized + Assign< T, T >, +{ #[ inline( always ) ] - fn assign_to_option< IntoSelf >( self, dst : &mut Option< Self > ) - where - Self : Sized + Assign< Self, Self >, + fn option_assign( & mut self, src : T ) { - match dst + match self { - Some( val ) => Assign::assign( val, self ), - None => *dst = Some( self ), + Some( self_ref ) => Assign::assign( self_ref, Into::< T >::into( src ) ), + None => * self = Some( src ), } } +} +#[ cfg( any( feature = "types_component_assign" ) ) ] +mod sealed +{ + pub trait Sealed {} + impl< T > Sealed for Option< T > + where + T : Sized + super::Assign< T, T >, + {} } -/// The `AssignWithType` trait provides a mechanism to set a component on an object, utilizing the type information explicitly. This trait extends the functionality of `SetComponen`t by allowing implementers to specify the component's type at the method call site, enhancing expressiveness in code that manipulates object states. -/// -/// ### Method Detail +/// The `AssignWithType` trait provides a mechanism to set a component on an object, +/// utilizing the type information explicitly. This trait extends the functionality of `Assign` +/// by allowing implementers to specify the component's type at the method call site, +/// enhancing expressiveness in code that manipulates object states. /// -/// - `assign_with_type::< T, IntoT >( &mut self, component : IntoT )` -/// -/// This method allows an implementer of `SetWithTyp`e to set a component on self where the component's type is T, and the input value is of type `IntoT`, which can be converted into `T`. This method bridges the gap between dynamic type usage and static type enforcement, providing a flexible yet type-safe interface for modifying object states. +/// # Type Parameters /// -/// ### Type Parameters +/// - `T`: The type of the component to be set on the implementing object. This specifies +/// the exact type expected by the object as its component. +/// - `IntoT`: A type that can be converted into `T`, providing flexibility in the types of values +/// that can be used to set the component. /// -/// - `T` : The type of the component to be set on the implementing object. This specifies the exact type expected by the object as its component. -/// - `IntoT` : A type that can be converted into T, providing flexibility in the types of values that can be used to set the component. +/// # Examples /// -/// ### Example +/// Implementing `AssignWithType` to set a username on a struct: /// /// ```rust /// use former_types::{ Assign, AssignWithType }; // use crate `former` instead of crate `former_types` unless you need to use crate `former_types` directly @@ -88,7 +148,6 @@ where /// } /// /// impl< IntoT : Into< String > > Assign< String, IntoT > for UserProfile -// where String: From< String >, /// { /// fn assign( &mut self, component : IntoT ) /// { @@ -97,17 +156,29 @@ where /// } /// /// let mut user_profile = UserProfile { username : String::new() }; -/// user_profile.assign_with_type::< String, _ >( "john_doe" ); +/// user_profile.assign_with_type::< String, _ >("john_doe"); /// /// assert_eq!( user_profile.username, "john_doe" ); /// ``` -/// - #[ cfg( any( feature = "types_component_assign" ) ) ] pub trait AssignWithType { - /// Function to set value of a component by its type. - fn assign_with_type< T, IntoT >( &mut self, component : IntoT ) + /// Sets the value of a component by its type. + /// + /// This method allows an implementer of `AssignWithType` to set a component on `self` + /// where the component's type is `T`, and the input value is of type `IntoT`, which can be + /// converted into `T`. This method bridges the gap between dynamic type usage and static type + /// enforcement, providing a flexible yet type-safe interface for modifying object states. + /// + /// # Parameters + /// + /// - `component`: The value to assign to the component. + /// + /// # Type Parameters + /// + /// - `T`: The type of the component to be set on the implementing object. + /// - `IntoT`: A type that can be converted into `T`. + fn assign_with_type< T, IntoT >( & mut self, component : IntoT ) where IntoT : Into< T >, Self : Assign< T, IntoT >; @@ -116,14 +187,12 @@ pub trait AssignWithType #[ cfg( any( feature = "types_component_assign" ) ) ] impl< S > AssignWithType for S { - #[ inline( always ) ] - fn assign_with_type< T, IntoT >( &mut self, component : IntoT ) + fn assign_with_type< T, IntoT >( & mut self, component : IntoT ) where IntoT : Into< T >, Self : Assign< T, IntoT >, { Assign::< T, IntoT >::assign( self, component ); } - } From 2759f92ac1db21fa54a73ba05a915c0e887f17f4 Mon Sep 17 00:00:00 2001 From: wandalen Date: Thu, 30 May 2024 18:38:21 +0300 Subject: [PATCH 34/59] derive_tools, former: implementing ComponentAssign for all attributes --- .../src/derive_former/field_attrs.rs | 69 +++++++++++++++++-- .../src/derive_former/struct_attrs.rs | 48 +++++++++++-- 2 files changed, 109 insertions(+), 8 deletions(-) diff --git a/module/core/former_meta/src/derive_former/field_attrs.rs b/module/core/former_meta/src/derive_former/field_attrs.rs index 2cb01981ec..2a7c6b287b 100644 --- a/module/core/former_meta/src/derive_former/field_attrs.rs +++ b/module/core/former_meta/src/derive_former/field_attrs.rs @@ -295,7 +295,22 @@ where #[ inline( always ) ] fn assign( &mut self, component : IntoT ) { - self.scalar = Some( component.into() ); + let component = component.into(); + self.scalar.option_assign( component ); + } +} + +impl< IntoT > Assign< AttributeScalarSetter, IntoT > for AttributeScalarSetter +where + IntoT : Into< AttributeScalarSetter >, +{ + #[ inline( always ) ] + fn assign( &mut self, component : IntoT ) + { + let component = component.into(); + self.name.assign( component.name ); + self.setter.assign( component.setter ); + self.debug.assign( component.debug ); } } @@ -455,7 +470,22 @@ where #[ inline( always ) ] fn assign( &mut self, component : IntoT ) { - self.subform_scalar = Some( component.into() ); + let component = component.into(); + self.subform_scalar.option_assign( component ); + } +} + +impl< IntoT > Assign< AttributeSubformScalarSetter, IntoT > for AttributeSubformScalarSetter +where + IntoT : Into< AttributeSubformScalarSetter >, +{ + #[ inline( always ) ] + fn assign( &mut self, component : IntoT ) + { + let component = component.into(); + self.name.assign( component.name ); + self.setter.assign( component.setter ); + self.debug.assign( component.debug ); } } @@ -617,7 +647,23 @@ where #[ inline( always ) ] fn assign( &mut self, component : IntoT ) { - self.subform_collection = Some( component.into() ); + let component = component.into(); + self.subform_collection.option_assign( component ); + } +} + +impl< IntoT > Assign< AttributeSubformCollectionSetter, IntoT > for AttributeSubformCollectionSetter +where + IntoT : Into< AttributeSubformCollectionSetter >, +{ + #[ inline( always ) ] + fn assign( &mut self, component : IntoT ) + { + let component = component.into(); + self.name.assign( component.name ); + self.setter.assign( component.setter ); + self.debug.assign( component.debug ); + self.definition.assign( component.definition ); } } @@ -797,7 +843,22 @@ where #[ inline( always ) ] fn assign( &mut self, component : IntoT ) { - self.subform_entry = Some( component.into() ); + let component = component.into(); + self.subform_entry.option_assign( component ); + } +} + +impl< IntoT > Assign< AttributeSubformEntrySetter, IntoT > for AttributeSubformEntrySetter +where + IntoT : Into< AttributeSubformEntrySetter >, +{ + #[ inline( always ) ] + fn assign( &mut self, component : IntoT ) + { + let component = component.into(); + self.name.assign( component.name ); + self.setter.assign( component.setter ); + self.debug.assign( component.debug ); } } diff --git a/module/core/former_meta/src/derive_former/struct_attrs.rs b/module/core/former_meta/src/derive_former/struct_attrs.rs index f88ca65a71..b5567b3eb5 100644 --- a/module/core/former_meta/src/derive_former/struct_attrs.rs +++ b/module/core/former_meta/src/derive_former/struct_attrs.rs @@ -13,7 +13,7 @@ use macro_tools:: AttributePropertyOptionalSingletone, }; -use former_types::{ Assign }; +use former_types::{ Assign, OptionExt }; /// Represents the attributes of a struct, including storage fields, mutator, and perform attributes. @@ -205,7 +205,20 @@ where #[ inline( always ) ] fn assign( &mut self, component : IntoT ) { - self.storage_fields = Some( component.into() ); + let component = component.into(); + self.storage_fields.option_assign( component ); + } +} + +impl< IntoT > Assign< AttributeStorageFields, IntoT > for AttributeStorageFields +where + IntoT : Into< AttributeStorageFields >, +{ + #[ inline( always ) ] + fn assign( &mut self, component : IntoT ) + { + let component = component.into(); + self.fields = component.fields; } } @@ -275,7 +288,21 @@ where #[ inline( always ) ] fn assign( &mut self, component : IntoT ) { - self.mutator = component.into(); + let component = component.into(); + self.mutator.assign( component ); + } +} + +impl< IntoT > Assign< AttributeMutator, IntoT > for AttributeMutator +where + IntoT : Into< AttributeMutator >, +{ + #[ inline( always ) ] + fn assign( &mut self, component : IntoT ) + { + let component = component.into(); + self.custom.assign( component.custom ); + self.debug.assign( component.debug ); } } @@ -406,7 +433,20 @@ where #[ inline( always ) ] fn assign( &mut self, component : IntoT ) { - self.perform = Some( component.into() ); + let component = component.into(); + self.perform.option_assign( component ); + } +} + +impl< IntoT > Assign< AttributePerform, IntoT > for AttributePerform +where + IntoT : Into< AttributePerform >, +{ + #[ inline( always ) ] + fn assign( &mut self, component : IntoT ) + { + let component = component.into(); + self.signature = component.signature; } } From 023e5f71e0386e0aa719b91488b5a93f4ebd07b0 Mon Sep 17 00:00:00 2001 From: wandalen Date: Thu, 30 May 2024 19:10:07 +0300 Subject: [PATCH 35/59] derive_tools, former: implementing ComponentAssign for all attributes --- .../inc/former_tests/attribute_multiple.rs | 36 +++++++++++++++++++ module/core/former/tests/inc/mod.rs | 1 + .../src/derive_former/field_attrs.rs | 3 +- .../src/attr_prop/boolean_optional.rs | 2 +- .../src/attr_prop/singletone_optional.rs | 2 +- .../macro_tools/src/attr_prop/syn_optional.rs | 2 +- 6 files changed, 42 insertions(+), 4 deletions(-) create mode 100644 module/core/former/tests/inc/former_tests/attribute_multiple.rs diff --git a/module/core/former/tests/inc/former_tests/attribute_multiple.rs b/module/core/former/tests/inc/former_tests/attribute_multiple.rs new file mode 100644 index 0000000000..bb9ac77920 --- /dev/null +++ b/module/core/former/tests/inc/former_tests/attribute_multiple.rs @@ -0,0 +1,36 @@ +#[ allow( unused_imports ) ] +use super::*; + +#[ derive( Debug, PartialEq, the_module::Former ) ] +pub struct Struct1 +{ + + #[ former( default = collection_tools::vec![ 1, 2, 3 ] ) ] + #[ former( default = collection_tools::vec![ 2, 3, 4 ] ) ] + vec_ints : Vec< i32 >, + +} + +// + +tests_impls! +{ + fn test_complex() + { + let command = Struct1::former().form(); + let expected = Struct1 + { + vec_ints : collection_tools::vec![ 2, 3, 4 ], + }; + a_id!( command, expected ); + } +} + +// + +tests_index! +{ + test_complex, +} + +// xxx2 : write \ No newline at end of file diff --git a/module/core/former/tests/inc/mod.rs b/module/core/former/tests/inc/mod.rs index 5348cbcae6..ab57420b85 100644 --- a/module/core/former/tests/inc/mod.rs +++ b/module/core/former/tests/inc/mod.rs @@ -38,6 +38,7 @@ mod former_tests mod attribute_setter; mod attribute_alias; mod attribute_feature; + mod attribute_multiple; // = name collision diff --git a/module/core/former_meta/src/derive_former/field_attrs.rs b/module/core/former_meta/src/derive_former/field_attrs.rs index 2a7c6b287b..ef8a62e965 100644 --- a/module/core/former_meta/src/derive_former/field_attrs.rs +++ b/module/core/former_meta/src/derive_former/field_attrs.rs @@ -184,7 +184,8 @@ where #[ inline( always ) ] fn assign( &mut self, component : IntoT ) { - self.default = component.into(); + // panic!( "" ); + self.default.assign( component.into() ); } } diff --git a/module/core/macro_tools/src/attr_prop/boolean_optional.rs b/module/core/macro_tools/src/attr_prop/boolean_optional.rs index 070d0b6476..4b614abc71 100644 --- a/module/core/macro_tools/src/attr_prop/boolean_optional.rs +++ b/module/core/macro_tools/src/attr_prop/boolean_optional.rs @@ -42,7 +42,7 @@ where let component = component.into(); match component.0 { - Some( val ) => { self.0.get_or_insert( val ); }, + Some( val ) => { self.0 = Some( val ); }, None => {}, } } diff --git a/module/core/macro_tools/src/attr_prop/singletone_optional.rs b/module/core/macro_tools/src/attr_prop/singletone_optional.rs index 6c2b7a5452..39c3dd9940 100644 --- a/module/core/macro_tools/src/attr_prop/singletone_optional.rs +++ b/module/core/macro_tools/src/attr_prop/singletone_optional.rs @@ -78,7 +78,7 @@ where let component = component.into(); match component.0 { - Some( val ) => { self.0.get_or_insert( val ); }, + Some( val ) => { self.0 = Some( val ); }, None => {}, } } diff --git a/module/core/macro_tools/src/attr_prop/syn_optional.rs b/module/core/macro_tools/src/attr_prop/syn_optional.rs index 2d1bcd3b96..3b4f546ff6 100644 --- a/module/core/macro_tools/src/attr_prop/syn_optional.rs +++ b/module/core/macro_tools/src/attr_prop/syn_optional.rs @@ -47,7 +47,7 @@ where let component = component.into(); match component.0 { - Some( val ) => { self.0.get_or_insert( val ); }, + Some( val ) => { self.0 = Some( val ); }, None => {}, } } From 1a227a3367931bc4f3e5c99d6f4a1055c240f819 Mon Sep 17 00:00:00 2001 From: wandalen Date: Thu, 30 May 2024 19:31:26 +0300 Subject: [PATCH 36/59] derive_tools, former: implementing ComponentAssign for all attributes --- .../from_inner_variants_duplicates_some_off_default_off.rs | 5 +---- .../core/former/tests/inc/former_tests/attribute_multiple.rs | 2 -- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/module/core/derive_tools/tests/inc/from_inner_variants_duplicates_some_off_default_off.rs b/module/core/derive_tools/tests/inc/from_inner_variants_duplicates_some_off_default_off.rs index 6445f17e8e..f9cefa347c 100644 --- a/module/core/derive_tools/tests/inc/from_inner_variants_duplicates_some_off_default_off.rs +++ b/module/core/derive_tools/tests/inc/from_inner_variants_duplicates_some_off_default_off.rs @@ -10,10 +10,8 @@ pub enum GetData Nothing, Nothing2, FromString( String ), - // #[ from( on ) ] #[ from( on ) ] - // #[ from( debug ) ] - // xxx : should that work? + #[ from( debug ) ] FromString2( String ), FromPair( String, String ), #[ from( on ) ] @@ -24,7 +22,6 @@ pub enum GetData } // == begin of generated - // == end of generated include!( "./only_test/from_inner_variants_duplicates.rs" ); diff --git a/module/core/former/tests/inc/former_tests/attribute_multiple.rs b/module/core/former/tests/inc/former_tests/attribute_multiple.rs index bb9ac77920..55c3745e8d 100644 --- a/module/core/former/tests/inc/former_tests/attribute_multiple.rs +++ b/module/core/former/tests/inc/former_tests/attribute_multiple.rs @@ -32,5 +32,3 @@ tests_index! { test_complex, } - -// xxx2 : write \ No newline at end of file From ff77b3f708e28b537777558c75055274dbe3ccb7 Mon Sep 17 00:00:00 2001 From: wandalen Date: Thu, 30 May 2024 19:31:34 +0300 Subject: [PATCH 37/59] derive_tools, former: implementing ComponentAssign for all attributes --- .../inc/from_inner_variants_duplicates_some_off_default_off.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/core/derive_tools/tests/inc/from_inner_variants_duplicates_some_off_default_off.rs b/module/core/derive_tools/tests/inc/from_inner_variants_duplicates_some_off_default_off.rs index f9cefa347c..9d60a25204 100644 --- a/module/core/derive_tools/tests/inc/from_inner_variants_duplicates_some_off_default_off.rs +++ b/module/core/derive_tools/tests/inc/from_inner_variants_duplicates_some_off_default_off.rs @@ -11,7 +11,7 @@ pub enum GetData Nothing2, FromString( String ), #[ from( on ) ] - #[ from( debug ) ] + // #[ from( debug ) ] FromString2( String ), FromPair( String, String ), #[ from( on ) ] From dfd69322c28fa8ae7b5d0a91649b92791ebfc29e Mon Sep 17 00:00:00 2001 From: wandalen Date: Thu, 30 May 2024 19:36:59 +0300 Subject: [PATCH 38/59] macro_tools : defalt markers for props --- module/core/macro_tools/src/attr_prop.rs | 7 ++++++- module/core/macro_tools/src/attr_prop/boolean.rs | 7 ++++++- module/core/macro_tools/src/attr_prop/boolean_optional.rs | 7 ++++++- module/core/macro_tools/src/attr_prop/syn.rs | 7 ++++++- module/core/macro_tools/src/attr_prop/syn_optional.rs | 7 ++++++- 5 files changed, 30 insertions(+), 5 deletions(-) diff --git a/module/core/macro_tools/src/attr_prop.rs b/module/core/macro_tools/src/attr_prop.rs index 1435cbbeed..4e5020eff2 100644 --- a/module/core/macro_tools/src/attr_prop.rs +++ b/module/core/macro_tools/src/attr_prop.rs @@ -145,15 +145,20 @@ pub mod exposed #[ allow( unused_imports ) ] pub use super:: { + singletone::AttributePropertySingletone, singletone::AttributePropertySingletoneMarker, singletone_optional::AttributePropertyOptionalSingletone, singletone_optional::AttributePropertyOptionalSingletoneMarker, - boolean::AttributePropertyBoolean, + boolean::AttributePropertyBooleanMarker, boolean_optional::AttributePropertyOptionalBoolean, + boolean_optional::AttributePropertyOptionalBooleanMarker, syn::AttributePropertySyn, + syn::AttributePropertySynMarker, syn_optional::AttributePropertyOptionalSyn, + syn_optional::AttributePropertyOptionalSynMarker, + }; } diff --git a/module/core/macro_tools/src/attr_prop/boolean.rs b/module/core/macro_tools/src/attr_prop/boolean.rs index d4d1220d7f..3e3a144202 100644 --- a/module/core/macro_tools/src/attr_prop/boolean.rs +++ b/module/core/macro_tools/src/attr_prop/boolean.rs @@ -6,6 +6,11 @@ use crate::*; use former_types::Assign; +/// Default marker for `AttributePropertyBoolean`. +/// Used if no marker is defined as parameter. +#[ derive( Debug, Default, Clone, Copy ) ] +pub struct AttributePropertyBooleanMarker; + /// A generic boolean attribute property. /// Defaults to `false`. /// @@ -104,7 +109,7 @@ use former_types::Assign; /// which is then parsed into the `MyAttributes` struct. The resulting `MyAttributes` instance is printed to the console. #[ derive( Debug, Default, Clone, Copy ) ] -pub struct AttributePropertyBoolean< Marker >( bool, ::core::marker::PhantomData< Marker > ); +pub struct AttributePropertyBoolean< Marker = AttributePropertyBooleanMarker >( bool, ::core::marker::PhantomData< Marker > ); impl< Marker > AttributePropertyBoolean< Marker > { diff --git a/module/core/macro_tools/src/attr_prop/boolean_optional.rs b/module/core/macro_tools/src/attr_prop/boolean_optional.rs index 4b614abc71..680803f4c8 100644 --- a/module/core/macro_tools/src/attr_prop/boolean_optional.rs +++ b/module/core/macro_tools/src/attr_prop/boolean_optional.rs @@ -6,10 +6,15 @@ use crate::*; use former_types::Assign; +/// Default marker for `AttributePropertyOptionalSingletone`. +/// Used if no marker is defined as parameter. +#[ derive( Debug, Default, Clone, Copy ) ] +pub struct AttributePropertyOptionalBooleanMarker; + /// A generic optional boolean attribute property: `Option< bool >`. /// Defaults to `false`. #[ derive( Debug, Default, Clone, Copy ) ] -pub struct AttributePropertyOptionalBoolean< Marker >( Option< bool >, ::core::marker::PhantomData< Marker > ); +pub struct AttributePropertyOptionalBoolean< Marker = AttributePropertyOptionalBooleanMarker >( Option< bool >, ::core::marker::PhantomData< Marker > ); impl< Marker > AttributePropertyOptionalBoolean< Marker > { diff --git a/module/core/macro_tools/src/attr_prop/syn.rs b/module/core/macro_tools/src/attr_prop/syn.rs index 4b265dde97..c60a21cfdd 100644 --- a/module/core/macro_tools/src/attr_prop/syn.rs +++ b/module/core/macro_tools/src/attr_prop/syn.rs @@ -5,12 +5,17 @@ use crate::*; use former_types::Assign; +/// Default marker for `AttributePropertySyn`. +/// Used if no marker is defined as parameter. +#[ derive( Debug, Default, Clone, Copy ) ] +pub struct AttributePropertySynMarker; + /// /// Property of an attribute which simply wraps one of the standard `syn` types. /// #[ derive( Debug, Clone ) ] -pub struct AttributePropertySyn< T, Marker >( T, ::core::marker::PhantomData< Marker > ) +pub struct AttributePropertySyn< T, Marker = AttributePropertySynMarker >( T, ::core::marker::PhantomData< Marker > ) where T : syn::parse::Parse + quote::ToTokens; diff --git a/module/core/macro_tools/src/attr_prop/syn_optional.rs b/module/core/macro_tools/src/attr_prop/syn_optional.rs index 3b4f546ff6..d595e9496a 100644 --- a/module/core/macro_tools/src/attr_prop/syn_optional.rs +++ b/module/core/macro_tools/src/attr_prop/syn_optional.rs @@ -5,12 +5,17 @@ use crate::*; use former_types::Assign; +/// Default marker for `AttributePropertyOptionalSyn`. +/// Used if no marker is defined as parameter. +#[ derive( Debug, Default, Clone, Copy ) ] +pub struct AttributePropertyOptionalSynMarker; + /// /// Property of an attribute which simply wraps one of the standard `syn` types and keeps it optional. /// #[ derive( Debug, Clone ) ] -pub struct AttributePropertyOptionalSyn< T, Marker >( Option< T >, ::core::marker::PhantomData< Marker > ) +pub struct AttributePropertyOptionalSyn< T, Marker = AttributePropertyOptionalSynMarker >( Option< T >, ::core::marker::PhantomData< Marker > ) where T : syn::parse::Parse + quote::ToTokens; From d6cc5dee0571738949218ec990b8edc53c472888 Mon Sep 17 00:00:00 2001 From: wandalen Date: Thu, 30 May 2024 19:40:20 +0300 Subject: [PATCH 39/59] all derives : avoid checking is attribute known --- .../core/derive_tools_meta/src/derive/from.rs | 23 +++++++++++-------- .../src/derive_former/field_attrs.rs | 11 ++++----- .../src/derive_former/struct_attrs.rs | 9 ++++---- module/core/macro_tools/Readme.md | 6 +---- .../examples/macro_tools_attr_prop.rs | 11 +++++---- .../core/macro_tools/src/attr_prop/boolean.rs | 2 -- 6 files changed, 30 insertions(+), 32 deletions(-) diff --git a/module/core/derive_tools_meta/src/derive/from.rs b/module/core/derive_tools_meta/src/derive/from.rs index 31412b8154..2a03cab8d4 100644 --- a/module/core/derive_tools_meta/src/derive/from.rs +++ b/module/core/derive_tools_meta/src/derive/from.rs @@ -456,10 +456,11 @@ impl ItemAttributes let key_ident = attr.path().get_ident().ok_or_else( || error( attr ) )?; let key_str = format!( "{}", key_ident ); - if attr::is_standard( &key_str ) - { - continue; - } + // attributes does not have to be known + // if attr::is_standard( &key_str ) + // { + // continue; + // } match key_str.as_ref() { @@ -648,16 +649,18 @@ impl FieldAttributes let key_ident = attr.path().get_ident().ok_or_else( || error( attr ) )?; let key_str = format!( "{}", key_ident ); - if attr::is_standard( &key_str ) - { - continue; - } + // attributes does not have to be known + // if attr::is_standard( &key_str ) + // { + // continue; + // } match key_str.as_ref() { FieldAttributeConfig::KEYWORD => result.assign( FieldAttributeConfig::from_meta( attr )? ), - "debug" => {} - _ => return Err( error( attr ) ), + "debug" => {}, + _ => {}, + // _ => return Err( error( attr ) ), } } diff --git a/module/core/former_meta/src/derive_former/field_attrs.rs b/module/core/former_meta/src/derive_former/field_attrs.rs index ef8a62e965..cfb4e91e36 100644 --- a/module/core/former_meta/src/derive_former/field_attrs.rs +++ b/module/core/former_meta/src/derive_former/field_attrs.rs @@ -87,13 +87,12 @@ impl FieldAttributes let key_ident = attr.path().get_ident().ok_or_else( || error( attr ) )?; let key_str = format!( "{}", key_ident ); - // Skip standard attributes - if attr::is_standard( &key_str ) - { - continue; - } + // // Skip standard attributes + // if attr::is_standard( &key_str ) + // { + // continue; + // } // attributes does not have to be known - // xxx // Match the attribute key and assign to the appropriate field match key_str.as_ref() diff --git a/module/core/former_meta/src/derive_former/struct_attrs.rs b/module/core/former_meta/src/derive_former/struct_attrs.rs index b5567b3eb5..2c693c3eac 100644 --- a/module/core/former_meta/src/derive_former/struct_attrs.rs +++ b/module/core/former_meta/src/derive_former/struct_attrs.rs @@ -65,10 +65,11 @@ impl ItemAttributes let key_ident = attr.path().get_ident().ok_or_else( || error( attr ) )?; let key_str = format!( "{}", key_ident ); - if attr::is_standard( &key_str ) - { - continue; - } + // attributes does not have to be known + // if attr::is_standard( &key_str ) + // { + // continue; + // } match key_str.as_ref() { diff --git a/module/core/macro_tools/Readme.md b/module/core/macro_tools/Readme.md index 039313e81f..62e2e0013a 100644 --- a/module/core/macro_tools/Readme.md +++ b/module/core/macro_tools/Readme.md @@ -140,15 +140,11 @@ fn main() { let key_ident = attr.path().get_ident().ok_or_else( || error( attr ) )?; let key_str = format!( "{}", key_ident ); - if attr::is_standard( & key_str ) - { - continue; - } match key_str.as_ref() { AttributeMutator::KEYWORD => result.assign( AttributeMutator::from_meta( attr )? ), "debug" => {}, - _ => return Err( error( attr ) ), + _ => {}, } } diff --git a/module/core/macro_tools/examples/macro_tools_attr_prop.rs b/module/core/macro_tools/examples/macro_tools_attr_prop.rs index 20c8df5c48..4625e15154 100644 --- a/module/core/macro_tools/examples/macro_tools_attr_prop.rs +++ b/module/core/macro_tools/examples/macro_tools_attr_prop.rs @@ -86,15 +86,16 @@ fn main() { let key_ident = attr.path().get_ident().ok_or_else( || error( attr ) )?; let key_str = format!( "{}", key_ident ); - if attr::is_standard( & key_str ) - { - continue; - } + // if attr::is_standard( & key_str ) + // { + // continue; + // } match key_str.as_ref() { AttributeMutator::KEYWORD => result.assign( AttributeMutator::from_meta( attr )? ), "debug" => {}, - _ => return Err( error( attr ) ), + _ => {}, + // _ => return Err( error( attr ) ), } } diff --git a/module/core/macro_tools/src/attr_prop/boolean.rs b/module/core/macro_tools/src/attr_prop/boolean.rs index 3e3a144202..4472b3ae42 100644 --- a/module/core/macro_tools/src/attr_prop/boolean.rs +++ b/module/core/macro_tools/src/attr_prop/boolean.rs @@ -128,8 +128,6 @@ impl< Marker > AttributePropertyBoolean< Marker > } } -// xxx : introduce default markers for all properties - impl< Marker, IntoT > Assign< AttributePropertyBoolean< Marker >, IntoT > for AttributePropertyBoolean< Marker > where From 97a358ca4090cd40d7d1628c9967d7c2f7cc1988 Mon Sep 17 00:00:00 2001 From: wandalen Date: Thu, 30 May 2024 19:53:42 +0300 Subject: [PATCH 40/59] derive_tools: refactor from --- .../core/derive_tools_meta/src/derive/from.rs | 601 +++--------------- .../src/derive/from/field_attributes.rs | 252 ++++++++ .../src/derive/from/item_attributes.rs | 201 ++++++ .../src/derive_former/field_attrs.rs | 1 - .../src/derive_former/struct_attrs.rs | 1 - 5 files changed, 534 insertions(+), 522 deletions(-) create mode 100644 module/core/derive_tools_meta/src/derive/from/field_attributes.rs create mode 100644 module/core/derive_tools_meta/src/derive/from/item_attributes.rs diff --git a/module/core/derive_tools_meta/src/derive/from.rs b/module/core/derive_tools_meta/src/derive/from.rs index 2a03cab8d4..536196ce63 100644 --- a/module/core/derive_tools_meta/src/derive/from.rs +++ b/module/core/derive_tools_meta/src/derive/from.rs @@ -7,13 +7,12 @@ use macro_tools:: item_struct, struct_like::StructLike, Result, - AttributeComponent, - AttributePropertyComponent, - // AttributePropertySingletone, - AttributePropertyOptionalSingletone, }; -use former_types::Assign; +mod field_attributes; +use field_attributes::*; +mod item_attributes; +use item_attributes::*; // @@ -143,102 +142,29 @@ pub fn from( input : proc_macro::TokenStream ) -> Result< proc_macro2::TokenStre } // qqq : document, add example of generated code -fn variant_generate +fn generate_unit ( item_name : &syn::Ident, - item_attrs : &ItemAttributes, generics_impl : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, generics_ty : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, generics_where: &syn::punctuated::Punctuated< syn::WherePredicate, syn::token::Comma >, - variant : &syn::Variant, - original_input : &proc_macro::TokenStream, ) --> Result< proc_macro2::TokenStream > +-> proc_macro2::TokenStream { - let variant_name = &variant.ident; - let fields = &variant.fields; - let attrs = FieldAttributes::from_attrs( variant.attrs.iter() )?; - - if !attrs.config.enabled.value( item_attrs.config.enabled.value( true ) ) - { - return Ok( qt!{} ) - } - - if fields.len() <= 0 - { - return Ok( qt!{} ) - } - - let ( args, use_src ) = if fields.len() == 1 - { - let field = fields.iter().next().unwrap(); - ( - qt!{ #field }, - qt!{ src }, - ) - } - else - { - let src_i = ( 0..fields.len() ).map( | e | - { - let i = syn::Index::from( e ); - qt!{ src.#i, } - }); - ( - qt!{ #fields }, - qt!{ #( #src_i )* }, - // qt!{ src.0, src.1 }, - ) - }; - - if attrs.config.debug.value( false ) + qt! { - let debug = format! - ( - r#" -#[ automatically_derived ] -impl< {0} > From< {args} > for {item_name}< {1} > -where - {2} -{{ - #[ inline ] - fn from( src : {args} ) -> Self - {{ - Self::{variant_name}( {use_src} ) - }} -}} - "#, - format!( "{}", qt!{ #generics_impl } ), - format!( "{}", qt!{ #generics_ty } ), - format!( "{}", qt!{ #generics_where } ), - ); - let about = format! - ( -r#"derive : From -item : {item_name} -field : {variant_name}"#, - ); - diag::report_print( about, original_input, debug ); - } - - Ok - ( - qt! + // impl From< () > for UnitStruct + impl< #generics_impl > From< () > for #item_name< #generics_ty > + where + #generics_where { - #[ automatically_derived ] - impl< #generics_impl > From< #args > for #item_name< #generics_ty > - where - #generics_where + #[ inline( always ) ] + fn from( src : () ) -> Self { - #[ inline ] - fn from( src : #args ) -> Self - { - Self::#variant_name( #use_src ) - } + Self } } - ) - + } } // qqq : document, add example of generated code @@ -385,466 +311,101 @@ fn generate_from_multiple_fields< 'a > } } - // qqq : document, add example of generated code -fn generate_unit +fn variant_generate ( item_name : &syn::Ident, + item_attrs : &ItemAttributes, generics_impl : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, generics_ty : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, generics_where: &syn::punctuated::Punctuated< syn::WherePredicate, syn::token::Comma >, + variant : &syn::Variant, + original_input : &proc_macro::TokenStream, ) --> proc_macro2::TokenStream -{ - qt! - { - // impl From< () > for UnitStruct - impl< #generics_impl > From< () > for #item_name< #generics_ty > - where - #generics_where - { - #[ inline( always ) ] - fn from( src : () ) -> Self - { - Self - } - } - } -} - -// == item attributes - -/// -/// Attributes of the whole tiem -/// - -/// Represents the attributes of a struct. Aggregates all its attributes. -#[ derive( Debug, Default ) ] -pub struct ItemAttributes -{ - /// Attribute for customizing generated code. - pub config : ItemAttributeConfig, -} - -impl ItemAttributes -{ - - pub fn from_attrs< 'a >( attrs : impl Iterator< Item = &'a syn::Attribute > ) -> Result< Self > - { - let mut result = Self::default(); - - let error = | attr : &syn::Attribute | -> syn::Error - { - let known_attributes = const_format::concatcp! - ( - "Known attirbutes are : ", - "debug", - ", ", ItemAttributeConfig::KEYWORD, - ".", - ); - syn_err! - ( - attr, - "Expects an attribute of format '#[ attribute( key1 = val1, key2 = val2 ) ]'\n {known_attributes}\n But got: '{}'", - qt!{ #attr } - ) - }; - - for attr in attrs - { - - let key_ident = attr.path().get_ident().ok_or_else( || error( attr ) )?; - let key_str = format!( "{}", key_ident ); - - // attributes does not have to be known - // if attr::is_standard( &key_str ) - // { - // continue; - // } - - match key_str.as_ref() - { - ItemAttributeConfig::KEYWORD => result.assign( ItemAttributeConfig::from_meta( attr )? ), - "debug" => {} - _ => {}, - // _ => return Err( error( attr ) ), - // attributes does not have to be known - } - } - - Ok( result ) - } - -} - -/// -/// Attribute to hold parameters of forming for a specific field or variant. -/// For example to avoid code From generation for it. -/// -/// `#[ from( on ) ]` -/// - -#[ derive( Debug, Default ) ] -pub struct ItemAttributeConfig -{ - /// Specifies whether `From` implementation for fields/variants should be generated by default. - /// Can be altered using `on` and `off` attributes. But default it's `on`. - /// `#[ from( on ) ]` - `From` is generated unless `off` for the field/variant is explicitly specified. - /// `#[ from( off ) ]` - `From` is not generated unless `on` for the field/variant is explicitly specified. - pub enabled : AttributePropertyEnabled, -} - -impl AttributeComponent for ItemAttributeConfig -{ - const KEYWORD : &'static str = "from"; - - fn from_meta( attr : &syn::Attribute ) -> Result< Self > - { - match attr.meta - { - syn::Meta::List( ref meta_list ) => - { - return syn::parse2::< ItemAttributeConfig >( meta_list.tokens.clone() ); - }, - syn::Meta::Path( ref _path ) => - { - return Ok( Default::default() ) - }, - _ => return_syn_err!( attr, "Expects an attribute of format `#[ from( on ) ]`. \nGot: {}", qt!{ #attr } ), - } - } - -} - -impl< IntoT > Assign< ItemAttributeConfig, IntoT > for ItemAttributes -where - IntoT : Into< ItemAttributeConfig >, -{ - #[ inline( always ) ] - fn assign( &mut self, component : IntoT ) - { - self.config.assign( component.into() ); - } -} - -impl< IntoT > Assign< ItemAttributeConfig, IntoT > for ItemAttributeConfig -where - IntoT : Into< ItemAttributeConfig >, +-> Result< proc_macro2::TokenStream > { - #[ inline( always ) ] - fn assign( &mut self, component : IntoT ) - { - let component = component.into(); - self.enabled.assign( component.enabled ); - } -} + let variant_name = &variant.ident; + let fields = &variant.fields; + let attrs = FieldAttributes::from_attrs( variant.attrs.iter() )?; -impl< IntoT > Assign< AttributePropertyEnabled, IntoT > for ItemAttributeConfig -where - IntoT : Into< AttributePropertyEnabled >, -{ - #[ inline( always ) ] - fn assign( &mut self, component : IntoT ) + if !attrs.config.enabled.value( item_attrs.config.enabled.value( true ) ) { - self.enabled = component.into(); + return Ok( qt!{} ) } -} -impl syn::parse::Parse for ItemAttributeConfig -{ - fn parse( input : syn::parse::ParseStream< '_ > ) -> syn::Result< Self > + if fields.len() <= 0 { - let mut result = Self::default(); - - let error = | ident : &syn::Ident | -> syn::Error - { - let known = const_format::concatcp! - ( - "Known entries of attribute ", ItemAttributeConfig::KEYWORD, " are : ", - EnabledMarker::KEYWORD_ON, - ", ", EnabledMarker::KEYWORD_OFF, - ".", - ); - syn_err! - ( - ident, - r#"Expects an attribute of format '#[ from( off ) ]' - {known} - But got: '{}' -"#, - qt!{ #ident } - ) - }; - - while !input.is_empty() - { - let lookahead = input.lookahead1(); - if lookahead.peek( syn::Ident ) - { - let ident : syn::Ident = input.parse()?; - match ident.to_string().as_str() - { - EnabledMarker::KEYWORD_ON => result.assign( AttributePropertyEnabled::from( true ) ), - EnabledMarker::KEYWORD_OFF => result.assign( AttributePropertyEnabled::from( false ) ), - _ => return Err( error( &ident ) ), - } - } - else - { - return Err( lookahead.error() ); - } - - // Optional comma handling - if input.peek( syn::Token![ , ] ) - { - input.parse::< syn::Token![ , ] >()?; - } - } - - Ok( result ) + return Ok( qt!{} ) } -} - -// == field attributes - -/// -/// Attributes of a field / variant -/// - -/// Represents the attributes of a struct. Aggregates all its attributes. -#[ derive( Debug, Default ) ] -pub struct FieldAttributes -{ - /// Attribute for customizing generated code. - pub config : FieldAttributeConfig, -} - -impl FieldAttributes -{ - pub fn from_attrs< 'a >( attrs : impl Iterator< Item = &'a syn::Attribute > ) -> Result< Self > + let ( args, use_src ) = if fields.len() == 1 { - let mut result = Self::default(); - - let error = | attr : &syn::Attribute | -> syn::Error - { - let known_attributes = const_format::concatcp! - ( - "Known attirbutes are : ", - "debug", - ", ", FieldAttributeConfig::KEYWORD, - ".", - ); - syn_err! - ( - attr, - "Expects an attribute of format '#[ attribute( key1 = val1, key2 = val2 ) ]'\n {known_attributes}\n But got: '{}'", - qt!{ #attr } - ) - }; - - for attr in attrs - { - - let key_ident = attr.path().get_ident().ok_or_else( || error( attr ) )?; - let key_str = format!( "{}", key_ident ); - - // attributes does not have to be known - // if attr::is_standard( &key_str ) - // { - // continue; - // } - - match key_str.as_ref() - { - FieldAttributeConfig::KEYWORD => result.assign( FieldAttributeConfig::from_meta( attr )? ), - "debug" => {}, - _ => {}, - // _ => return Err( error( attr ) ), - } - } - - Ok( result ) + let field = fields.iter().next().unwrap(); + ( + qt!{ #field }, + qt!{ src }, + ) } - -} - -/// -/// Attribute to hold parameters of forming for a specific field or variant. -/// For example to avoid code From generation for it. -/// -/// `#[ from( on ) ]` -/// - -#[ derive( Debug, Default ) ] -pub struct FieldAttributeConfig -{ - /// Specifies whether we should generate From implementation for the field. - /// Can be altered using `on` and `off` attributes - pub enabled : AttributePropertyEnabled, - /// Specifies whether to print a sketch of generated `From` or not. - /// Defaults to `false`, which means no code is printed unless explicitly requested. - pub debug : AttributePropertyDebug, - // qqq : apply debug properties to all brenches, not only enums -} - -impl AttributeComponent for FieldAttributeConfig -{ - const KEYWORD : &'static str = "from"; - - fn from_meta( attr : &syn::Attribute ) -> Result< Self > + else { - match attr.meta + let src_i = ( 0..fields.len() ).map( | e | { - syn::Meta::List( ref meta_list ) => - { - return syn::parse2::< FieldAttributeConfig >( meta_list.tokens.clone() ); - }, - syn::Meta::Path( ref _path ) => - { - return Ok( Default::default() ) - }, - _ => return_syn_err!( attr, "Expects an attribute of format `#[ from( on ) ]`. \nGot: {}", qt!{ #attr } ), - } - } - -} - -impl< IntoT > Assign< FieldAttributeConfig, IntoT > for FieldAttributes -where - IntoT : Into< FieldAttributeConfig >, -{ - #[ inline( always ) ] - fn assign( &mut self, component : IntoT ) - { - self.config.assign( component.into() ); - } -} - -impl< IntoT > Assign< FieldAttributeConfig, IntoT > for FieldAttributeConfig -where - IntoT : Into< FieldAttributeConfig >, -{ - #[ inline( always ) ] - fn assign( &mut self, component : IntoT ) - { - let component = component.into(); - self.enabled.assign( component.enabled ); - self.debug.assign( component.debug ); - } -} + let i = syn::Index::from( e ); + qt!{ src.#i, } + }); + ( + qt!{ #fields }, + qt!{ #( #src_i )* }, + // qt!{ src.0, src.1 }, + ) + }; -impl< IntoT > Assign< AttributePropertyEnabled, IntoT > for FieldAttributeConfig -where - IntoT : Into< AttributePropertyEnabled >, -{ - #[ inline( always ) ] - fn assign( &mut self, component : IntoT ) + if attrs.config.debug.value( false ) { - self.enabled = component.into(); - } -} - -impl< IntoT > Assign< AttributePropertyDebug, IntoT > for FieldAttributeConfig + let debug = format! + ( + r#" +#[ automatically_derived ] +impl< {0} > From< {args} > for {item_name}< {1} > where - IntoT : Into< AttributePropertyDebug >, -{ - #[ inline( always ) ] - fn assign( &mut self, component : IntoT ) - { - self.debug = component.into(); + {2} +{{ + #[ inline ] + fn from( src : {args} ) -> Self + {{ + Self::{variant_name}( {use_src} ) + }} +}} + "#, + format!( "{}", qt!{ #generics_impl } ), + format!( "{}", qt!{ #generics_ty } ), + format!( "{}", qt!{ #generics_where } ), + ); + let about = format! + ( +r#"derive : From +item : {item_name} +field : {variant_name}"#, + ); + diag::report_print( about, original_input, debug ); } -} -impl syn::parse::Parse for FieldAttributeConfig -{ - fn parse( input : syn::parse::ParseStream< '_ > ) -> syn::Result< Self > - { - let mut result = Self::default(); - - let error = | ident : &syn::Ident | -> syn::Error - { - let known = const_format::concatcp! - ( - "Known entries of attribute ", FieldAttributeConfig::KEYWORD, " are : ", - AttributePropertyDebug::KEYWORD, - ", ", EnabledMarker::KEYWORD_ON, - ", ", EnabledMarker::KEYWORD_OFF, - ".", - ); - syn_err! - ( - ident, - r#"Expects an attribute of format '#[ from( on ) ]' - {known} - But got: '{}' -"#, - qt!{ #ident } - ) - }; - - while !input.is_empty() + Ok + ( + qt! { - let lookahead = input.lookahead1(); - if lookahead.peek( syn::Ident ) + #[ automatically_derived ] + impl< #generics_impl > From< #args > for #item_name< #generics_ty > + where + #generics_where { - let ident : syn::Ident = input.parse()?; - match ident.to_string().as_str() + #[ inline ] + fn from( src : #args ) -> Self { - AttributePropertyDebug::KEYWORD => result.assign( AttributePropertyDebug::from( true ) ), - EnabledMarker::KEYWORD_ON => result.assign( AttributePropertyEnabled::from( true ) ), - EnabledMarker::KEYWORD_OFF => result.assign( AttributePropertyEnabled::from( false ) ), - _ => return Err( error( &ident ) ), + Self::#variant_name( #use_src ) } } - else - { - return Err( lookahead.error() ); - } - - // Optional comma handling - if input.peek( syn::Token![ , ] ) - { - input.parse::< syn::Token![ , ] >()?; - } } + ) - Ok( result ) - } -} - -// == attribute properties - -/// Marker type for attribute property to specify whether to provide a generated code as a hint. -/// Defaults to `false`, which means no debug is provided unless explicitly requested. -#[ derive( Debug, Default, Clone, Copy ) ] -pub struct AttributePropertyDebugMarker; - -impl AttributePropertyComponent for AttributePropertyDebugMarker -{ - const KEYWORD : &'static str = "debug"; -} - -/// Specifies whether to provide a generated code as a hint. -/// Defaults to `false`, which means no debug is provided unless explicitly requested. -pub type AttributePropertyDebug = AttributePropertyOptionalSingletone< AttributePropertyDebugMarker >; - -// = - -/// Marker type for attribute property to indicates whether `From` implementation for fields/variants should be generated. -#[ derive( Debug, Default, Clone, Copy ) ] -pub struct EnabledMarker; - -impl EnabledMarker -{ - /// Keywords for parsing this attribute property. - pub const KEYWORD_OFF : &'static str = "off"; - /// Keywords for parsing this attribute property. - pub const KEYWORD_ON : &'static str = "on"; } - -/// Specifies whether `From` implementation for fields/variants should be generated. -/// Can be altered using `on` and `off` attributes. But default it's `on`. -pub type AttributePropertyEnabled = AttributePropertyOptionalSingletone< EnabledMarker >; - -// == diff --git a/module/core/derive_tools_meta/src/derive/from/field_attributes.rs b/module/core/derive_tools_meta/src/derive/from/field_attributes.rs new file mode 100644 index 0000000000..8ff1e9f56f --- /dev/null +++ b/module/core/derive_tools_meta/src/derive/from/field_attributes.rs @@ -0,0 +1,252 @@ +use super::*; +use macro_tools:: +{ + Result, + AttributeComponent, + AttributePropertyComponent, + AttributePropertyOptionalSingletone, +}; + +use former_types::Assign; + +/// +/// Attributes of a field / variant +/// + +/// Represents the attributes of a struct. Aggregates all its attributes. +#[ derive( Debug, Default ) ] +pub struct FieldAttributes +{ + /// Attribute for customizing generated code. + pub config : FieldAttributeConfig, +} + +impl FieldAttributes +{ + + pub fn from_attrs< 'a >( attrs : impl Iterator< Item = &'a syn::Attribute > ) -> Result< Self > + { + let mut result = Self::default(); + + let error = | attr : &syn::Attribute | -> syn::Error + { + let known_attributes = const_format::concatcp! + ( + "Known attirbutes are : ", + "debug", + ", ", FieldAttributeConfig::KEYWORD, + ".", + ); + syn_err! + ( + attr, + "Expects an attribute of format '#[ attribute( key1 = val1, key2 = val2 ) ]'\n {known_attributes}\n But got: '{}'", + qt!{ #attr } + ) + }; + + for attr in attrs + { + + let key_ident = attr.path().get_ident().ok_or_else( || error( attr ) )?; + let key_str = format!( "{}", key_ident ); + + // attributes does not have to be known + // if attr::is_standard( &key_str ) + // { + // continue; + // } + + match key_str.as_ref() + { + FieldAttributeConfig::KEYWORD => result.assign( FieldAttributeConfig::from_meta( attr )? ), + "debug" => {}, + _ => {}, + // _ => return Err( error( attr ) ), + } + } + + Ok( result ) + } + +} + +/// +/// Attribute to hold parameters of forming for a specific field or variant. +/// For example to avoid code From generation for it. +/// +/// `#[ from( on ) ]` +/// + +#[ derive( Debug, Default ) ] +pub struct FieldAttributeConfig +{ + /// Specifies whether we should generate From implementation for the field. + /// Can be altered using `on` and `off` attributes + pub enabled : AttributePropertyEnabled, + /// Specifies whether to print a sketch of generated `From` or not. + /// Defaults to `false`, which means no code is printed unless explicitly requested. + pub debug : AttributePropertyDebug, + // qqq : apply debug properties to all brenches, not only enums +} + +impl AttributeComponent for FieldAttributeConfig +{ + const KEYWORD : &'static str = "from"; + + fn from_meta( attr : &syn::Attribute ) -> Result< Self > + { + match attr.meta + { + syn::Meta::List( ref meta_list ) => + { + return syn::parse2::< FieldAttributeConfig >( meta_list.tokens.clone() ); + }, + syn::Meta::Path( ref _path ) => + { + return Ok( Default::default() ) + }, + _ => return_syn_err!( attr, "Expects an attribute of format `#[ from( on ) ]`. \nGot: {}", qt!{ #attr } ), + } + } + +} + +impl< IntoT > Assign< FieldAttributeConfig, IntoT > for FieldAttributes +where + IntoT : Into< FieldAttributeConfig >, +{ + #[ inline( always ) ] + fn assign( &mut self, component : IntoT ) + { + self.config.assign( component.into() ); + } +} + +impl< IntoT > Assign< FieldAttributeConfig, IntoT > for FieldAttributeConfig +where + IntoT : Into< FieldAttributeConfig >, +{ + #[ inline( always ) ] + fn assign( &mut self, component : IntoT ) + { + let component = component.into(); + self.enabled.assign( component.enabled ); + self.debug.assign( component.debug ); + } +} + +impl< IntoT > Assign< AttributePropertyEnabled, IntoT > for FieldAttributeConfig +where + IntoT : Into< AttributePropertyEnabled >, +{ + #[ inline( always ) ] + fn assign( &mut self, component : IntoT ) + { + self.enabled = component.into(); + } +} + +impl< IntoT > Assign< AttributePropertyDebug, IntoT > for FieldAttributeConfig +where + IntoT : Into< AttributePropertyDebug >, +{ + #[ inline( always ) ] + fn assign( &mut self, component : IntoT ) + { + self.debug = component.into(); + } +} + +impl syn::parse::Parse for FieldAttributeConfig +{ + fn parse( input : syn::parse::ParseStream< '_ > ) -> syn::Result< Self > + { + let mut result = Self::default(); + + let error = | ident : &syn::Ident | -> syn::Error + { + let known = const_format::concatcp! + ( + "Known entries of attribute ", FieldAttributeConfig::KEYWORD, " are : ", + AttributePropertyDebug::KEYWORD, + ", ", EnabledMarker::KEYWORD_ON, + ", ", EnabledMarker::KEYWORD_OFF, + ".", + ); + syn_err! + ( + ident, + r#"Expects an attribute of format '#[ from( on ) ]' + {known} + But got: '{}' +"#, + qt!{ #ident } + ) + }; + + while !input.is_empty() + { + let lookahead = input.lookahead1(); + if lookahead.peek( syn::Ident ) + { + let ident : syn::Ident = input.parse()?; + match ident.to_string().as_str() + { + AttributePropertyDebug::KEYWORD => result.assign( AttributePropertyDebug::from( true ) ), + EnabledMarker::KEYWORD_ON => result.assign( AttributePropertyEnabled::from( true ) ), + EnabledMarker::KEYWORD_OFF => result.assign( AttributePropertyEnabled::from( false ) ), + _ => return Err( error( &ident ) ), + } + } + else + { + return Err( lookahead.error() ); + } + + // Optional comma handling + if input.peek( syn::Token![ , ] ) + { + input.parse::< syn::Token![ , ] >()?; + } + } + + Ok( result ) + } +} + +// == attribute properties + +/// Marker type for attribute property to specify whether to provide a generated code as a hint. +/// Defaults to `false`, which means no debug is provided unless explicitly requested. +#[ derive( Debug, Default, Clone, Copy ) ] +pub struct AttributePropertyDebugMarker; + +impl AttributePropertyComponent for AttributePropertyDebugMarker +{ + const KEYWORD : &'static str = "debug"; +} + +/// Specifies whether to provide a generated code as a hint. +/// Defaults to `false`, which means no debug is provided unless explicitly requested. +pub type AttributePropertyDebug = AttributePropertyOptionalSingletone< AttributePropertyDebugMarker >; + +// = + +/// Marker type for attribute property to indicates whether `From` implementation for fields/variants should be generated. +#[ derive( Debug, Default, Clone, Copy ) ] +pub struct EnabledMarker; + +impl EnabledMarker +{ + /// Keywords for parsing this attribute property. + pub const KEYWORD_OFF : &'static str = "off"; + /// Keywords for parsing this attribute property. + pub const KEYWORD_ON : &'static str = "on"; +} + +/// Specifies whether `From` implementation for fields/variants should be generated. +/// Can be altered using `on` and `off` attributes. But default it's `on`. +pub type AttributePropertyEnabled = AttributePropertyOptionalSingletone< EnabledMarker >; + +// == diff --git a/module/core/derive_tools_meta/src/derive/from/item_attributes.rs b/module/core/derive_tools_meta/src/derive/from/item_attributes.rs new file mode 100644 index 0000000000..78cc32f2d4 --- /dev/null +++ b/module/core/derive_tools_meta/src/derive/from/item_attributes.rs @@ -0,0 +1,201 @@ +use super::*; +use macro_tools:: +{ + Result, + AttributeComponent, +}; + +use former_types::Assign; + +/// +/// Attributes of the whole tiem +/// + +/// Represents the attributes of a struct. Aggregates all its attributes. +#[ derive( Debug, Default ) ] +pub struct ItemAttributes +{ + /// Attribute for customizing generated code. + pub config : ItemAttributeConfig, +} + +impl ItemAttributes +{ + + pub fn from_attrs< 'a >( attrs : impl Iterator< Item = &'a syn::Attribute > ) -> Result< Self > + { + let mut result = Self::default(); + + let error = | attr : &syn::Attribute | -> syn::Error + { + let known_attributes = const_format::concatcp! + ( + "Known attirbutes are : ", + "debug", + ", ", ItemAttributeConfig::KEYWORD, + ".", + ); + syn_err! + ( + attr, + "Expects an attribute of format '#[ attribute( key1 = val1, key2 = val2 ) ]'\n {known_attributes}\n But got: '{}'", + qt!{ #attr } + ) + }; + + for attr in attrs + { + + let key_ident = attr.path().get_ident().ok_or_else( || error( attr ) )?; + let key_str = format!( "{}", key_ident ); + + // attributes does not have to be known + // if attr::is_standard( &key_str ) + // { + // continue; + // } + + match key_str.as_ref() + { + ItemAttributeConfig::KEYWORD => result.assign( ItemAttributeConfig::from_meta( attr )? ), + "debug" => {} + _ => {}, + // _ => return Err( error( attr ) ), + // attributes does not have to be known + } + } + + Ok( result ) + } + +} + +/// +/// Attribute to hold parameters of forming for a specific field or variant. +/// For example to avoid code From generation for it. +/// +/// `#[ from( on ) ]` +/// + +#[ derive( Debug, Default ) ] +pub struct ItemAttributeConfig +{ + /// Specifies whether `From` implementation for fields/variants should be generated by default. + /// Can be altered using `on` and `off` attributes. But default it's `on`. + /// `#[ from( on ) ]` - `From` is generated unless `off` for the field/variant is explicitly specified. + /// `#[ from( off ) ]` - `From` is not generated unless `on` for the field/variant is explicitly specified. + pub enabled : AttributePropertyEnabled, +} + +impl AttributeComponent for ItemAttributeConfig +{ + const KEYWORD : &'static str = "from"; + + fn from_meta( attr : &syn::Attribute ) -> Result< Self > + { + match attr.meta + { + syn::Meta::List( ref meta_list ) => + { + return syn::parse2::< ItemAttributeConfig >( meta_list.tokens.clone() ); + }, + syn::Meta::Path( ref _path ) => + { + return Ok( Default::default() ) + }, + _ => return_syn_err!( attr, "Expects an attribute of format `#[ from( on ) ]`. \nGot: {}", qt!{ #attr } ), + } + } + +} + +impl< IntoT > Assign< ItemAttributeConfig, IntoT > for ItemAttributes +where + IntoT : Into< ItemAttributeConfig >, +{ + #[ inline( always ) ] + fn assign( &mut self, component : IntoT ) + { + self.config.assign( component.into() ); + } +} + +impl< IntoT > Assign< ItemAttributeConfig, IntoT > for ItemAttributeConfig +where + IntoT : Into< ItemAttributeConfig >, +{ + #[ inline( always ) ] + fn assign( &mut self, component : IntoT ) + { + let component = component.into(); + self.enabled.assign( component.enabled ); + } +} + +impl< IntoT > Assign< AttributePropertyEnabled, IntoT > for ItemAttributeConfig +where + IntoT : Into< AttributePropertyEnabled >, +{ + #[ inline( always ) ] + fn assign( &mut self, component : IntoT ) + { + self.enabled = component.into(); + } +} + +impl syn::parse::Parse for ItemAttributeConfig +{ + fn parse( input : syn::parse::ParseStream< '_ > ) -> syn::Result< Self > + { + let mut result = Self::default(); + + let error = | ident : &syn::Ident | -> syn::Error + { + let known = const_format::concatcp! + ( + "Known entries of attribute ", ItemAttributeConfig::KEYWORD, " are : ", + EnabledMarker::KEYWORD_ON, + ", ", EnabledMarker::KEYWORD_OFF, + ".", + ); + syn_err! + ( + ident, + r#"Expects an attribute of format '#[ from( off ) ]' + {known} + But got: '{}' +"#, + qt!{ #ident } + ) + }; + + while !input.is_empty() + { + let lookahead = input.lookahead1(); + if lookahead.peek( syn::Ident ) + { + let ident : syn::Ident = input.parse()?; + match ident.to_string().as_str() + { + EnabledMarker::KEYWORD_ON => result.assign( AttributePropertyEnabled::from( true ) ), + EnabledMarker::KEYWORD_OFF => result.assign( AttributePropertyEnabled::from( false ) ), + _ => return Err( error( &ident ) ), + } + } + else + { + return Err( lookahead.error() ); + } + + // Optional comma handling + if input.peek( syn::Token![ , ] ) + { + input.parse::< syn::Token![ , ] >()?; + } + } + + Ok( result ) + } +} + +// == diff --git a/module/core/former_meta/src/derive_former/field_attrs.rs b/module/core/former_meta/src/derive_former/field_attrs.rs index cfb4e91e36..0dd3cf3edc 100644 --- a/module/core/former_meta/src/derive_former/field_attrs.rs +++ b/module/core/former_meta/src/derive_former/field_attrs.rs @@ -3,7 +3,6 @@ use super::*; use macro_tools:: { - attr, Result, AttributeComponent, AttributePropertyComponent, diff --git a/module/core/former_meta/src/derive_former/struct_attrs.rs b/module/core/former_meta/src/derive_former/struct_attrs.rs index 2c693c3eac..44e8273292 100644 --- a/module/core/former_meta/src/derive_former/struct_attrs.rs +++ b/module/core/former_meta/src/derive_former/struct_attrs.rs @@ -6,7 +6,6 @@ use super::*; use macro_tools:: { - attr, Result, AttributeComponent, AttributePropertyComponent, From af609be85adde1b893e9a1932d3cbbfabd072034 Mon Sep 17 00:00:00 2001 From: wandalen Date: Thu, 30 May 2024 19:54:42 +0300 Subject: [PATCH 41/59] derive_tools: tasks --- module/core/derive_tools_meta/src/derive/from.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/module/core/derive_tools_meta/src/derive/from.rs b/module/core/derive_tools_meta/src/derive/from.rs index 536196ce63..d05b416235 100644 --- a/module/core/derive_tools_meta/src/derive/from.rs +++ b/module/core/derive_tools_meta/src/derive/from.rs @@ -229,7 +229,7 @@ fn generate_from_single_field } } -// qqq : for Petro : document, add example of generated code +// qqq : document, add example of generated code fn generate_from_multiple_fields_named< 'a > ( item_name : &syn::Ident, @@ -360,6 +360,7 @@ fn variant_generate ) }; + // qqq : make `debug` working for all branches if attrs.config.debug.value( false ) { let debug = format! From ff6866d60efda8b83899aed6eb95e429e176cf2e Mon Sep 17 00:00:00 2001 From: wandalen Date: Thu, 30 May 2024 20:24:36 +0300 Subject: [PATCH 42/59] former_types-v2.2.0 --- Cargo.toml | 2 +- module/core/former_types/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 2819bbf5ad..60eb787745 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -215,7 +215,7 @@ path = "module/core/former_meta" default-features = false [workspace.dependencies.former_types] -version = "~2.1.0" +version = "~2.2.0" path = "module/core/former_types" default-features = false diff --git a/module/core/former_types/Cargo.toml b/module/core/former_types/Cargo.toml index 95ca657ed3..d6b6ca5fb3 100644 --- a/module/core/former_types/Cargo.toml +++ b/module/core/former_types/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "former_types" -version = "2.1.0" +version = "2.2.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", From 31530b2b9e93c90e0b78ee8defec93c96e13e965 Mon Sep 17 00:00:00 2001 From: wandalen Date: Thu, 30 May 2024 20:24:49 +0300 Subject: [PATCH 43/59] macro_tools-v0.27.0 --- Cargo.toml | 2 +- module/core/macro_tools/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 60eb787745..9911494f56 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -260,7 +260,7 @@ default-features = false ## macro tools [workspace.dependencies.macro_tools] -version = "~0.26.0" +version = "~0.27.0" path = "module/core/macro_tools" default-features = false diff --git a/module/core/macro_tools/Cargo.toml b/module/core/macro_tools/Cargo.toml index 76f03b758d..d6d8ce9d7b 100644 --- a/module/core/macro_tools/Cargo.toml +++ b/module/core/macro_tools/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "macro_tools" -version = "0.26.0" +version = "0.27.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", From 964b9349a4bae442e420ad6ff1c8b60819839c2d Mon Sep 17 00:00:00 2001 From: wandalen Date: Thu, 30 May 2024 20:25:11 +0300 Subject: [PATCH 44/59] derive_tools_meta-v0.22.0 --- Cargo.toml | 2 +- module/core/derive_tools_meta/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 9911494f56..52b9419895 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -118,7 +118,7 @@ default-features = false features = [ "enabled" ] [workspace.dependencies.derive_tools_meta] -version = "~0.21.0" +version = "~0.22.0" path = "module/core/derive_tools_meta" default-features = false features = [ "enabled" ] diff --git a/module/core/derive_tools_meta/Cargo.toml b/module/core/derive_tools_meta/Cargo.toml index 074cd08b82..a266fd1ee6 100644 --- a/module/core/derive_tools_meta/Cargo.toml +++ b/module/core/derive_tools_meta/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "derive_tools_meta" -version = "0.21.0" +version = "0.22.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", From 44f44883af68c5e0b89da436472c943bbd4979e8 Mon Sep 17 00:00:00 2001 From: wandalen Date: Thu, 30 May 2024 20:25:23 +0300 Subject: [PATCH 45/59] clone_dyn_meta-v0.17.0 --- Cargo.toml | 2 +- module/core/clone_dyn_meta/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 52b9419895..546afc3faa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -158,7 +158,7 @@ default-features = false features = [ "enabled" ] [workspace.dependencies.clone_dyn_meta] -version = "~0.16.0" +version = "~0.17.0" path = "module/core/clone_dyn_meta" features = [ "enabled" ] diff --git a/module/core/clone_dyn_meta/Cargo.toml b/module/core/clone_dyn_meta/Cargo.toml index 0cc0f336f6..e6d9bf304e 100644 --- a/module/core/clone_dyn_meta/Cargo.toml +++ b/module/core/clone_dyn_meta/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clone_dyn_meta" -version = "0.16.0" +version = "0.17.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", From f765b748123420293bc7090525a0b6f2f2100df0 Mon Sep 17 00:00:00 2001 From: wandalen Date: Thu, 30 May 2024 20:25:35 +0300 Subject: [PATCH 46/59] variadic_from-v0.18.0 --- Cargo.toml | 2 +- module/core/variadic_from/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 546afc3faa..afa951e9f2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -146,7 +146,7 @@ path = "module/alias/fundamental_data_type" default-features = false [workspace.dependencies.variadic_from] -version = "~0.17.0" +version = "~0.18.0" path = "module/core/variadic_from" default-features = false features = [ "enabled" ] diff --git a/module/core/variadic_from/Cargo.toml b/module/core/variadic_from/Cargo.toml index 4bd87fb11b..3a8aac6c6e 100644 --- a/module/core/variadic_from/Cargo.toml +++ b/module/core/variadic_from/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "variadic_from" -version = "0.17.0" +version = "0.18.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", From 5f402e83ee47c12eae0083ac3ee1ef8ec1427d78 Mon Sep 17 00:00:00 2001 From: wandalen Date: Thu, 30 May 2024 20:25:48 +0300 Subject: [PATCH 47/59] clone_dyn-v0.17.0 --- Cargo.toml | 2 +- module/core/clone_dyn/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index afa951e9f2..35a3a2a14f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -152,7 +152,7 @@ default-features = false features = [ "enabled" ] [workspace.dependencies.clone_dyn] -version = "~0.16.0" +version = "~0.17.0" path = "module/core/clone_dyn" default-features = false features = [ "enabled" ] diff --git a/module/core/clone_dyn/Cargo.toml b/module/core/clone_dyn/Cargo.toml index a409934586..f71ec38feb 100644 --- a/module/core/clone_dyn/Cargo.toml +++ b/module/core/clone_dyn/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clone_dyn" -version = "0.16.0" +version = "0.17.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", From 11629dd0695dc8772a0112180d5c31ee64072ad1 Mon Sep 17 00:00:00 2001 From: wandalen Date: Thu, 30 May 2024 20:26:16 +0300 Subject: [PATCH 48/59] derive_tools-v0.23.0 --- Cargo.toml | 2 +- module/core/derive_tools/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 35a3a2a14f..8ee1276268 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -112,7 +112,7 @@ default-features = false ## derive [workspace.dependencies.derive_tools] -version = "~0.22.0" +version = "~0.23.0" path = "module/core/derive_tools" default-features = false features = [ "enabled" ] diff --git a/module/core/derive_tools/Cargo.toml b/module/core/derive_tools/Cargo.toml index 3f33bc2770..d54788975c 100644 --- a/module/core/derive_tools/Cargo.toml +++ b/module/core/derive_tools/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "derive_tools" -version = "0.22.0" +version = "0.23.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", From 681751e589255dcd38cdde8b13e64b51f20748f9 Mon Sep 17 00:00:00 2001 From: wandalen Date: Thu, 30 May 2024 20:26:31 +0300 Subject: [PATCH 49/59] mod_interface_meta-v0.20.0 --- Cargo.toml | 2 +- module/core/mod_interface_meta/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 8ee1276268..58fb5d4f76 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -234,7 +234,7 @@ path = "module/core/mod_interface" default-features = false [workspace.dependencies.mod_interface_meta] -version = "~0.19.0" +version = "~0.20.0" path = "module/core/mod_interface_meta" default-features = false diff --git a/module/core/mod_interface_meta/Cargo.toml b/module/core/mod_interface_meta/Cargo.toml index 62b4c26d8e..b8e13dae71 100644 --- a/module/core/mod_interface_meta/Cargo.toml +++ b/module/core/mod_interface_meta/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mod_interface_meta" -version = "0.19.0" +version = "0.20.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", From 154217f59a4829f89d2f375943a4e67a8a9555a2 Mon Sep 17 00:00:00 2001 From: wandalen Date: Thu, 30 May 2024 20:26:41 +0300 Subject: [PATCH 50/59] error_tools-v0.14.0 --- Cargo.toml | 2 +- module/core/error_tools/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 58fb5d4f76..7a732f5ee2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -314,7 +314,7 @@ default-features = false ## error [workspace.dependencies.error_tools] -version = "~0.13.0" +version = "~0.14.0" path = "module/core/error_tools" default-features = false diff --git a/module/core/error_tools/Cargo.toml b/module/core/error_tools/Cargo.toml index e1398d3d64..1ef5cccee8 100644 --- a/module/core/error_tools/Cargo.toml +++ b/module/core/error_tools/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "error_tools" -version = "0.13.0" +version = "0.14.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", From 9a66dfb6c0f14091b713a4da5ca277298c91b4e4 Mon Sep 17 00:00:00 2001 From: wandalen Date: Thu, 30 May 2024 20:26:55 +0300 Subject: [PATCH 51/59] mod_interface-v0.20.0 --- Cargo.toml | 2 +- module/core/mod_interface/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 7a732f5ee2..42faacb5a5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -229,7 +229,7 @@ version = "~0.7.0" path = "module/core/impls_index_meta" [workspace.dependencies.mod_interface] -version = "~0.19.0" +version = "~0.20.0" path = "module/core/mod_interface" default-features = false diff --git a/module/core/mod_interface/Cargo.toml b/module/core/mod_interface/Cargo.toml index 381551f5d5..4876619e96 100644 --- a/module/core/mod_interface/Cargo.toml +++ b/module/core/mod_interface/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mod_interface" -version = "0.19.0" +version = "0.20.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", From 7bb81fd31756618181522d93eacd7cb4c4ffd82a Mon Sep 17 00:00:00 2001 From: wandalen Date: Thu, 30 May 2024 20:27:11 +0300 Subject: [PATCH 52/59] proper_path_tools-v0.6.0 --- Cargo.toml | 2 +- module/core/proper_path_tools/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 42faacb5a5..9a29685983 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -348,7 +348,7 @@ path = "module/alias/file_tools" default-features = false [workspace.dependencies.proper_path_tools] -version = "~0.5.0" +version = "~0.6.0" path = "module/core/proper_path_tools" default-features = false diff --git a/module/core/proper_path_tools/Cargo.toml b/module/core/proper_path_tools/Cargo.toml index 9122db09b5..7f432561a1 100644 --- a/module/core/proper_path_tools/Cargo.toml +++ b/module/core/proper_path_tools/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "proper_path_tools" -version = "0.5.0" +version = "0.6.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", From 15dc0dca26bd42b772068088f7bf94664be59edc Mon Sep 17 00:00:00 2001 From: wandalen Date: Thu, 30 May 2024 20:27:22 +0300 Subject: [PATCH 53/59] former_meta-v2.1.0 --- Cargo.toml | 2 +- module/core/former_meta/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 9a29685983..6d9b9b3f71 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -210,7 +210,7 @@ version = "=2.0.0" default-features = false [workspace.dependencies.former_meta] -version = "~2.0.0" +version = "~2.1.0" path = "module/core/former_meta" default-features = false diff --git a/module/core/former_meta/Cargo.toml b/module/core/former_meta/Cargo.toml index 8511f01c50..04ea67bfca 100644 --- a/module/core/former_meta/Cargo.toml +++ b/module/core/former_meta/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "former_meta" -version = "2.0.0" +version = "2.1.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", From fcc5a899f4844af0e3ef230e36ebad41e50cde77 Mon Sep 17 00:00:00 2001 From: wandalen Date: Thu, 30 May 2024 20:27:36 +0300 Subject: [PATCH 54/59] former-v2.1.0 --- Cargo.toml | 2 +- module/core/former/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 6d9b9b3f71..f00e4465f1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -200,7 +200,7 @@ path = "module/core/for_each" default-features = false [workspace.dependencies.former] -version = "~2.0.0" +version = "~2.1.0" path = "module/core/former" default-features = false diff --git a/module/core/former/Cargo.toml b/module/core/former/Cargo.toml index 645deff0c3..563b0cc329 100644 --- a/module/core/former/Cargo.toml +++ b/module/core/former/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "former" -version = "2.0.0" +version = "2.1.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", From f19f52166342112356bda0fba29ab03a9c72dc52 Mon Sep 17 00:00:00 2001 From: wandalen Date: Thu, 30 May 2024 20:27:53 +0300 Subject: [PATCH 55/59] strs_tools-v0.13.0 --- Cargo.toml | 2 +- module/core/strs_tools/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index f00e4465f1..20bc1c17f8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -326,7 +326,7 @@ path = "module/alias/werror" ## string tools [workspace.dependencies.strs_tools] -version = "~0.12.0" +version = "~0.13.0" path = "module/core/strs_tools" default-features = false diff --git a/module/core/strs_tools/Cargo.toml b/module/core/strs_tools/Cargo.toml index 1e4263e517..1bd6baf56f 100644 --- a/module/core/strs_tools/Cargo.toml +++ b/module/core/strs_tools/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "strs_tools" -version = "0.12.0" +version = "0.13.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", From 0db68687493170004d97aed93159c3ac487ce67c Mon Sep 17 00:00:00 2001 From: wandalen Date: Thu, 30 May 2024 20:28:13 +0300 Subject: [PATCH 56/59] wca-v0.17.0 --- Cargo.toml | 2 +- module/move/wca/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 20bc1c17f8..f2efbce459 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -403,7 +403,7 @@ default-features = false ## ca [workspace.dependencies.wca] -version = "~0.16.0" +version = "~0.17.0" path = "module/move/wca" diff --git a/module/move/wca/Cargo.toml b/module/move/wca/Cargo.toml index 397ec27c94..2d8184148e 100644 --- a/module/move/wca/Cargo.toml +++ b/module/move/wca/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wca" -version = "0.16.0" +version = "0.17.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", From ce19a161598050a4ac8a870fe7cac8123b3a2c54 Mon Sep 17 00:00:00 2001 From: wandalen Date: Thu, 30 May 2024 20:28:54 +0300 Subject: [PATCH 57/59] process_tools-v0.5.0 --- Cargo.toml | 2 +- module/core/process_tools/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index f2efbce459..6bf10d9927 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -356,7 +356,7 @@ default-features = false ## process tools [workspace.dependencies.process_tools] -version = "~0.4.0" +version = "~0.5.0" path = "module/core/process_tools" default-features = false diff --git a/module/core/process_tools/Cargo.toml b/module/core/process_tools/Cargo.toml index 8620c11659..20325bebf8 100644 --- a/module/core/process_tools/Cargo.toml +++ b/module/core/process_tools/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "process_tools" -version = "0.4.0" +version = "0.5.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", From 22838e55d88e00ec62b5092858c6ccdd67359b01 Mon Sep 17 00:00:00 2001 From: wandalen Date: Thu, 30 May 2024 20:29:07 +0300 Subject: [PATCH 58/59] crates_tools-v0.10.0 --- Cargo.toml | 2 +- module/move/crates_tools/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 6bf10d9927..0f37787951 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -457,7 +457,7 @@ version = "~0.5.0" path = "module/move/deterministic_rand" [workspace.dependencies.crates_tools] -version = "~0.9.0" +version = "~0.10.0" path = "module/move/crates_tools" diff --git a/module/move/crates_tools/Cargo.toml b/module/move/crates_tools/Cargo.toml index e97cdc78b9..4120a358df 100644 --- a/module/move/crates_tools/Cargo.toml +++ b/module/move/crates_tools/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "crates_tools" -version = "0.9.0" +version = "0.10.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", From 60c4a80ea77be123830cb5d8bb8056e5f68cf46c Mon Sep 17 00:00:00 2001 From: wandalen Date: Thu, 30 May 2024 20:30:37 +0300 Subject: [PATCH 59/59] willbe-v0.11.0 --- Cargo.toml | 2 +- module/move/willbe/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 0f37787951..4bfc9102a5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -417,7 +417,7 @@ path = "module/move/wcensor" ## willbe [workspace.dependencies.willbe] -version = "~0.10.0" +version = "~0.11.0" path = "module/move/willbe" diff --git a/module/move/willbe/Cargo.toml b/module/move/willbe/Cargo.toml index cd58c869d2..27fed31983 100644 --- a/module/move/willbe/Cargo.toml +++ b/module/move/willbe/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "willbe" -version = "0.10.0" +version = "0.11.0" edition = "2021" authors = [ "Kostiantyn Wandalen ",