diff --git a/Cargo.toml b/Cargo.toml index 132c5b038f..3cb9f9b628 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -92,7 +92,7 @@ default-features = false # path = "module/core/type_constructor_derive_pair_meta" [workspace.dependencies.interval_adapter] -version = "~0.19.0" +version = "~0.20.0" path = "module/core/interval_adapter" default-features = false features = [ "enabled" ] @@ -104,7 +104,7 @@ default-features = false features = [ "enabled" ] [workspace.dependencies.collection_tools] -version = "~0.4.0" +version = "~0.5.0" path = "module/core/collection_tools" default-features = false diff --git a/module/core/collection_tools/Cargo.toml b/module/core/collection_tools/Cargo.toml index 1c9f60b9b5..e244927ee5 100644 --- a/module/core/collection_tools/Cargo.toml +++ b/module/core/collection_tools/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "collection_tools" -version = "0.4.0" +version = "0.5.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", diff --git a/module/core/derive_tools/src/lib.rs b/module/core/derive_tools/src/lib.rs index 3e29da3f59..9401495344 100644 --- a/module/core/derive_tools/src/lib.rs +++ b/module/core/derive_tools/src/lib.rs @@ -2,13 +2,32 @@ #![ doc( html_logo_url = "https://raw.githubusercontent.com/Wandalen/wTools/master/asset/img/logo_v3_trans_square.png" ) ] #![ doc( html_favicon_url = "https://raw.githubusercontent.com/Wandalen/wTools/alpha/asset/img/logo_v3_trans_square_icon_small_v2.ico" ) ] #![ doc( html_root_url = "https://docs.rs/derive_tools/latest/derive_tools/" ) ] - -//! -//! Collection of derives which extend STD. -//! - #![ doc = include_str!( concat!( env!( "CARGO_MANIFEST_DIR" ), "/", "Readme.md" ) ) ] +// // xxx : implement derive new +// +// #[ derive( Debug, PartialEq, Default ) ] +// pub struct Property< Name > +// { +// name : Name, +// description : String, +// code : isize, +// } +// +// /// generated by new +// impl< Name > Property< Name > +// { +// #[ inline ] +// pub fn new< Description, Code >( name : Name, description : Description, code : Code ) -> Self +// where +// Name : core::convert::Into< Name >, +// Description : core::convert::Into< String >, +// Code : core::convert::Into< isize >, +// { +// Self { name : name.into(), description : description.into(), code : code.into() } +// } +// } + #[ cfg( feature = "enabled" ) ] pub mod wtools; @@ -56,7 +75,7 @@ mod derive_more // #[ cfg( feature = "derive_reflect" ) ] // pub mod reflect; -// use derive_tools_meta::Deref; +// use derive_tools_meta::Deref; // use derive_tools_meta::VariadicFrom; /// Namespace with dependencies. diff --git a/module/core/former/Readme.md b/module/core/former/Readme.md index 35aea33b92..89b702ba71 100644 --- a/module/core/former/Readme.md +++ b/module/core/former/Readme.md @@ -533,33 +533,41 @@ But it's also possible to completely override setter and write its own from scra # fn main() # { -use former::Former; - -/// Structure with a custom setter. -#[ derive( Debug, Former ) ] -pub struct StructWithCustomSetters -{ - #[ scalar( setter = false ) ] - word : String, -} - -impl StructWithCustomSettersFormer -{ + use former::Former; - // Custom alternative setter for `word` - pub fn word( mut self, value : impl Into< String > ) -> Self + /// Structure with a custom setter. + #[ derive( Debug, Former ) ] + pub struct StructWithCustomSetters { - debug_assert!( self.storage.word.is_none() ); - self.storage.word = Some( format!( "{}!", value.into() ) ); - self + // Use `hint = true` to gennerate sketch of setter. + #[ scalar( setter = false, hint = false ) ] + word : String, } -} + impl< Definition > StructWithCustomSettersFormer< Definition > + where + Definition : former::FormerDefinition< Storage = StructWithCustomSettersFormerStorage >, + { + // Custom alternative setter for `word` + #[ inline ] + pub fn word< Src >( mut self, src : Src ) -> Self + where + Src : ::core::convert::Into< String >, + { + debug_assert!( self.storage.word.is_none() ); + self.storage.word = Some( format!( "{}!", src.into() ) ); + self + } + } -let example = StructWithCustomSetters::former() -.word( "Hello" ) -.form(); -assert_eq!( example.word, "Hello!".to_string() ); + let example = StructWithCustomSetters::former() + .word( "Hello" ) + .form(); + assert_eq!( example.word, "Hello!".to_string() ); + dbg!( example ); + //> StructWithCustomSetters { + //> word: "Hello!", + //> } # } ``` @@ -638,7 +646,7 @@ Purpose of Storage: - **Intermediate State Holding**: Storage serves as a temporary repository for all the partially set properties and data of the object being formed. This functionality is essential in situations where the object's completion depends on multiple, potentially complex stages of configuration. - **Decoupling Configuration from Instantiation**: Storage separates the accumulation of configuration states from the actual creation of the final object. This separation fosters cleaner, more maintainable code, allowing developers to apply configurations in any order and manage interim states more efficiently, without compromising the integrity of the final object. -Storage is not just a passive container; it is an active part of a larger ecosystem that includes the former itself, a context, and a callback (often referred to as `FormingEnd`): +Storage is not just a passive collection; it is an active part of a larger ecosystem that includes the former itself, a context, and a callback (often referred to as `FormingEnd`): - **Former as an Active Manager**: The former is responsible for managing the storage, utilizing it to keep track of the object's evolving configuration. It orchestrates the formation process by handling intermediate states and preparing the object for its final form. - **Contextual Flexibility**: The context associated with the former adds an additional layer of flexibility, allowing the former to adjust its behavior based on the broader circumstances of the object's formation. This is particularly useful when the forming process involves conditions or states external to the object itself. @@ -646,129 +654,27 @@ Storage is not just a passive container; it is an active part of a larger ecosys These elements work in concert to ensure that the forming process is not only about building an object step-by-step but also about integrating it seamlessly into larger, more complex structures or systems. -## Concept of Definitions - -Definitions are utilized to encapsulate and manage generic parameters efficiently and avoid passing each parameter individually. - -Two key definition Traits: - -1. **`FormerDefinitionTypes`**: - - This trait outlines the essential components involved in the formation process, including the types of storage, the form being created, and the context used. It focuses on the types involved rather than the termination of the formation process. -2. **`FormerDefinition`**: - - Building upon `FormerDefinitionTypes`, this trait incorporates the `FormingEnd` callback, linking the formation types with a definitive ending. It specifies how the formation process should conclude, which may involve validations, transformations, or integrations into larger structures. - - The inclusion of the `End` type parameter specifies the end conditions of the formation process, effectively connecting the temporary state held in storage to its ultimate form. - -## Overview of Formation Traits - -The formation process utilizes several core traits, each serving a specific purpose in the lifecycle of entity creation. These traits ensure that entities are constructed methodically, adhering to a structured pattern that enhances maintainability and scalability. Below is a summary of these key traits: - -- `EntityToDefinition`: Links entities to their respective formation definitions which dictate their construction process. -- `EntityToFormer`: Connects entities with formers that are responsible for their step-by-step construction. -- `EntityToStorage`: Specifies the storage structures that temporarily hold the state of an entity during its formation. -- `FormerDefinition`, `FormerDefinitionTypes`: Define the essential properties and ending conditions of the formation process, ensuring entities are formed according to predetermined rules and logic. -- `Storage`: Establishes the fundamental interface for storage types used in the formation process, ensuring each can initialize to a default state. -- `StoragePreform`: Describes the transformation of storage from a mutable, intermediate state into the final, immutable state of the entity, crucial for accurately concluding the formation process. -- `FormerMutator`: Allows for custom mutation logic on the storage and context immediately before the formation process completes, ensuring last-minute adjustments are possible. -- `FormingEnd`: Specifies the closure action at the end of the formation process, which can transform or validate the final state of the entity. -- `FormingEndClosure`: Provides a flexible mechanism for dynamically handling the end of the formation process using closures, useful for complex scenarios. -- `FormerBegin`: Initiates a subforming process, managing how entities begin their formation in terms of storage and context setup. - -These traits collectively facilitate a robust and flexible builder pattern that supports complex object creation and configuration scenarios. - -## Example : Custom Definition - -Define a custom former definition and custom forming logic, and apply them to a container. - -The example showcases how to accumulate elements into a container and then transform them into a single result using a custom `FormingEnd` implementation. This pattern is useful for scenarios where the formation process involves aggregation or transformation of input elements into a different type or form. - -```rust -# #[ cfg( any( not( feature = "derive_former" ), not( feature = "enabled" ) ) ) ] -# fn main() {} - -# #[ cfg( all( feature = "derive_former", feature = "enabled" ) ) ] -# fn main() -# { - - // Define a struct `Sum` that will act as a custom former definition. - struct Sum; - - // Implement `FormerDefinitionTypes` for `Sum`. - // This trait defines the types used during the forming process. - impl former::FormerDefinitionTypes for Sum - { - type Storage = Vec; // Container for the integers. - type Formed = i32; // The final type after forming, which is a single integer. - type Context = (); // No additional context is used in this example. - } - - // Implement `FormerMutator` for `Sum`. - // This trait could include custom mutation logic applied during the forming process, but it's empty in this example. - impl former::FormerMutator for Sum - { - } - - // Implement `FormerDefinition` for `Sum`. - // This trait links the custom types to the former. - impl former::FormerDefinition for Sum - { - type Types = Sum; // Associate the `FormerDefinitionTypes` with `Sum`. - type End = Sum; // Use `Sum` itself as the end handler. - type Storage = Vec; // Specify the storage type. - type Formed = i32; // Specify the final formed type. - type Context = (); // Specify the context type, not used here. - } - - // Implement `FormingEnd` for `Sum`. - // This trait handles the final step of the forming process. - impl former::FormingEnd for Sum - { - fn call - ( - &self, - storage: < Sum as former::FormerDefinitionTypes >::Storage, - _context: Option< < Sum as former::FormerDefinitionTypes >::Context> - ) - -> < Sum as former::FormerDefinitionTypes >::Formed - { - // Sum all integers in the storage vector. - storage.iter().sum() - } - } - - // Use the custom `Former` to sum a list of integers. - let got = former::ContainerFormer::::new(Sum) - .add( 1 ) // Add an integer to the storage. - .add( 2 ) // Add another integer. - .add( 10 ) // Add another integer. - .form(); // Perform the form operation, which triggers the summing logic. - let exp = 13; // Expected result after summing 1, 2, and 10. - assert_eq!(got, exp); // Assert the result is as expected. - - dbg!(got); // Debug print the result to verify the output. - // > got = 13 - -# } -``` - ## Concept of subformer Subformers are specialized builders used within the former to construct nested or collection-based data structures like vectors, hash maps, and hash sets. They simplify the process of adding elements to these structures by providing a fluent interface that can be seamlessly integrated into the overall builder pattern of a parent struct. This approach allows for clean and intuitive initialization of complex data structures, enhancing code readability and maintainability. ## Types of Setters / Subformers -It's crucial to understand the differences among subform setters, container setters, and scalar setters: +Understanding the distinctions among the types of setters or subformers is essential for effectively employing the builder pattern in object construction. Each type of setter is designed to meet specific needs in building complex, structured data entities: -- **Scalar Setter**: Directly sets scalar values or simple fields within the forming entity. Unlike subform or container setters that manage complex objects or collections, scalar setters handle basic data types or individual fields. These are typically straightforward setter methods that do not involve nested formers or additional structuring. +- **Scalar Setter**: Handles the direct assignment of scalar values or simple fields within an entity. These setters manage basic data types or individual fields and do not involve nested formers or complex structuring. -- **Container Setter**: Returns a former of the container itself, offering an interface to manage the container as a whole rather than its individual elements. This type of setter is useful for applying configurations or validations to the entire collection, such as a `HashMap` of children. +- **Subform Collection Setter**: Facilitates the management of a collection as a whole by returning a former that provides an interface to configure the entire collection. This setter is beneficial for applying uniform configurations or validations to all elements in a collection, such as a `HashMap` of children. -- **Subform Setter**: Returns a former of an element within a container, providing an interface to individually form each element. For example, the `child` method acts as a subform setter, allowing for the addition and configuration of individual `Child` entities within the `Parent`'s `HashMap`. +- **Subform Entry Setter**: This setter allows for the individual formation of elements within a collection. It returns a former for each element, enabling detailed configuration and addition of complex elements within collections, exemplified by managing `Child` entities within a `Parent`'s `HashMap`. -Each type of setter is designed to address different needs in the formation process, ensuring that users can build complex, nested structures or simply set individual field values as required. +- **Subform Scalar Setter**: Similar to the subform entry setter but designed for scalar fields that have a former implementation. This setter does not collect instances into a collection because there is no collection involved, only a scalar field. It is used when the scalar field itself needs to be configured or modified through its dedicated former. -## Example : Container Setter for a Vector +These setters ensure that developers can precisely and efficiently set properties, manage collections, and configure complex structures within their applications. -This example demonstrates how to employ the `Former` trait to configure a `Vec` using a container setter in a structured manner. +## Example : Collection Setter for a Vector + +This example demonstrates how to employ the `Former` trait to configure a `Vec` using a collection setter in a structured manner. ```rust # #[ cfg( not( all( feature = "enabled", feature = "derive_former", not( feature = "no_std" ) ) ) ) ] @@ -781,7 +687,7 @@ This example demonstrates how to employ the `Former` trait to configure a `Vec` #[ derive( Debug, PartialEq, former::Former ) ] pub struct StructWithVec { - #[ container ] + #[ subform_collection ] vec : Vec< &'static str >, } @@ -798,13 +704,13 @@ This example demonstrates how to employ the `Former` trait to configure a `Vec` # } ``` -Try out `cargo run --example former_container_vector`. +Try out `cargo run --example former_collection_vector`.
-[See code](./examples/former_container_vector.rs). +[See code](./examples/former_collection_vector.rs). -## Example : Container Setter for a Hashmap +## Example : Collection Setter for a Hashmap -This example demonstrates how to effectively employ the `Former` trait to configure a `HashMap` using a container setter. +This example demonstrates how to effectively employ the `Former` trait to configure a `HashMap` using a collection setter. ```rust # #[ cfg( not( all( feature = "enabled", feature = "derive_former", not( feature = "no_std" ) ) ) ) ] @@ -818,7 +724,7 @@ This example demonstrates how to effectively employ the `Former` trait to config #[ derive( Debug, PartialEq, former::Former ) ] pub struct StructWithMap { - #[ container ] + #[ subform_collection ] map : HashMap< &'static str, &'static str >, } @@ -835,11 +741,11 @@ This example demonstrates how to effectively employ the `Former` trait to config # } ``` -Try out `cargo run --example former_container_hashmap`. +Try out `cargo run --example former_collection_hashmap`.
-[See code](./examples/former_container_hashmap.rs). +[See code](./examples/former_collection_hashmap.rs). -## Example : Container Setter for a Hashset +## Example : Collection Setter for a Hashset This example demonstrates the use of the `Former` trait to build a `collection_tools::HashSet` through subforming. @@ -855,7 +761,7 @@ This example demonstrates the use of the `Former` trait to build a `collection_t #[ derive( Debug, PartialEq, former::Former ) ] pub struct StructWithSet { - #[ container ] + #[ subform_collection ] set : HashSet< &'static str >, } @@ -872,15 +778,15 @@ This example demonstrates the use of the `Former` trait to build a `collection_t # } ``` -Try out `cargo run --example former_container_hashset`. +Try out `cargo run --example former_collection_hashset`.
-[See code](./examples/former_container_hashset.rs). +[See code](./examples/former_collection_hashset.rs). ## Example : Custom Scalar Setter -This example demonstrates the implementation of a scalar setter using the `Former` trait. Unlike the more complex subform and container setters shown in previous examples, this example focuses on a straightforward approach to directly set a scalar value within a parent entity. The `Parent` struct manages a `HashMap` of `Child` entities, and the scalar setter is used to set the entire `HashMap` directly. +This example demonstrates the implementation of a scalar setter using the `Former` trait. Unlike the more complex subform and collection setters shown in previous examples, this example focuses on a straightforward approach to directly set a scalar value within a parent entity. The `Parent` struct manages a `HashMap` of `Child` entities, and the scalar setter is used to set the entire `HashMap` directly. -The `child` function within `ParentFormer` is a custom subform setter that plays a crucial role. It uniquely employs the `ChildFormer` to add and configure children by their names within the parent's builder pattern. This method demonstrates a powerful technique for integrating subformers that manage specific elements of a container—each child entity in this case. +The `child` function within `ParentFormer` is a custom subform setter that plays a crucial role. It uniquely employs the `ChildFormer` to add and configure children by their names within the parent's builder pattern. This method demonstrates a powerful technique for integrating subformers that manage specific elements of a collection—each child entity in this case. ```rust # #[ cfg( not( all( feature = "enabled", feature = "derive_former", not( feature = "no_std" ) ) ) ) ] @@ -952,7 +858,7 @@ The `child` function within `ParentFormer` is a custom subform setter that plays # } ``` -In this example, the `Parent` struct functions as a container for multiple `Child` structs, each identified by a unique child name. The `ParentFormer` implements a custom method `child`, which serves as a subformer for adding `Child` instances into the `Parent`. +In this example, the `Parent` struct functions as a collection for multiple `Child` structs, each identified by a unique child name. The `ParentFormer` implements a custom method `child`, which serves as a subformer for adding `Child` instances into the `Parent`. - **Child Definition**: Each `Child` consists of a `name` and a `description`, and we derive `Former` to enable easy setting of these properties using a builder pattern. - **Parent Definition**: It holds a collection of `Child` objects in a `HashMap`. The `#[setter(false)]` attribute is used to disable the default setter, and a custom method `child` is defined to facilitate the addition of children with specific attributes. @@ -962,11 +868,86 @@ Try out `cargo run --example former_custom_scalar_setter`.
[See code](./examples/former_custom_scalar_setter.rs). -## Example : Custom Container Setter +## Example : Custom Subform Scalar Setter + +Implementation of a custom subform scalar setter using the `Former` trait in Rust. + +This example focuses on the usage of a subform scalar setter to manage complex scalar types within a parent structure. +Unlike more general subform setters that handle collections, this setter specifically configures scalar fields that have +their own formers, allowing for detailed configuration within a nested builder pattern. + +```rust + +# #[ cfg( not( all( feature = "enabled", feature = "derive_former", not( feature = "no_std" ) ) ) ) ] +# fn main() +# {} +# +# // Ensures the example only compiles when the appropriate features are enabled. +# #[ cfg( all( feature = "enabled", feature = "derive_former", not( feature = "no_std" ) ) ) ] +# fn main() +# { -This example demonstrates the use of container setters to manage complex nested data structures with the `Former` trait, focusing on a parent-child relationship structured around a container `HashMap`. Unlike typical builder patterns that add individual elements using subform setters, this example uses a container setter to manage the entire collection of children. + use former::Former; + + // Child struct with Former derived for builder pattern support + #[ derive( Debug, PartialEq, Former ) ] + // Optional: Use `#[debug]` to expand and debug generated code. + // #[debug] + pub struct Child + { + name : String, + description : String, + } -The `child` function within `ParentFormer` is a custom subform setter that plays a crucial role. It uniquely employs the `ChildFormer` to add and configure children by their names within the parent's builder pattern. This method demonstrates a powerful technique for integrating subformers that manage specific elements of a container—each child entity in this case. + // Parent struct designed to hold a single Child instance using subform scalar + #[ derive( Debug, PartialEq, Former ) ] + // Optional: Use `#[debug]` to expand and debug generated code. + // #[debug] + pub struct Parent + { + // 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 ) ] + child : Child, + } + + /// Extends `ParentFormer` to include a method that initializes and configures a subformer for the 'child' field. + /// This function demonstrates the dynamic addition of a named child, leveraging a subformer to specify detailed properties. + impl< Definition > ParentFormer< Definition > + where + Definition : former::FormerDefinition< Storage = < Parent as former::EntityToStorage >::Storage >, + { + #[ inline( always ) ] + pub fn child( self, name : &str ) -> ChildAsSubformer< Self, impl ChildAsSubformerEnd< Self > > + { + self._child_subform_scalar::< ChildFormer< _ >, _, >().name( name ) + } + } + + // Creating an instance of `Parent` using the builder pattern to configure `Child` + let ca = Parent::former() + .child( "echo" ) // starts the configuration of the `child` subformer + .description( "prints all subjects and properties" ) // sets additional properties for the `Child` + .end() // finalize the child configuration + .form(); // finalize the Parent configuration + + dbg!( &ca ); // Outputs the structured data for review + // Expected output: + //> Parent { + //> child: Child { + //> name: "echo", + //> description: "prints all subjects and properties", + //> }, + //> } + +# } +``` + +## Example : Custom Subform Collection Setter + +This example demonstrates the use of collection setters to manage complex nested data structures with the `Former` trait, focusing on a parent-child relationship structured around a collection `HashMap`. Unlike typical builder patterns that add individual elements using subform setters, this example uses a collection setter to manage the entire collection of children. + +The `child` function within `ParentFormer` is a custom subform setter that plays a crucial role. It uniquely employs the `ChildFormer` to add and configure children by their names within the parent's builder pattern. This method demonstrates a powerful technique for integrating subformers that manage specific elements of a collection—each child entity in this case. ```rust # #[ cfg( not( all( feature = "enabled", feature = "derive_former", not( feature = "no_std" ) ) ) ) ] @@ -1039,15 +1020,15 @@ The `child` function within `ParentFormer` is a custom subform setter that plays # } ``` -Try out `cargo run --example former_custom_container_setter`. +Try out `cargo run --example former_custom_subform_collection`.
-[See code](./examples/former_custom_container_setter.rs). +[See code](./examples/former_custom_subform_collection.rs). -## Example : Custom Subform Setter +## Example : Custom Subform Entry Setter This example illustrates the implementation of nested builder patterns using the `Former` trait, emphasizing a parent-child relationship. Here, the `Parent` struct utilizes `ChildFormer` as a custom subformer to dynamically manage its `child` field—a `HashMap`. Each child in the `HashMap` is uniquely identified and configured via the `ChildFormer`. -The `child` function within `ParentFormer` is a custom subform setter that plays a crucial role. It uniquely employs the `ChildFormer` to add and configure children by their names within the parent's builder pattern. This method demonstrates a powerful technique for integrating subformers that manage specific elements of a container—each child entity in this case. +The `child` function within `ParentFormer` is a custom subform setter that plays a crucial role. It uniquely employs the `ChildFormer` to add and configure children by their names within the parent's builder pattern. This method demonstrates a powerful technique for integrating subformers that manage specific elements of a collection—each child entity in this case. ```rust # #[ cfg( not( all( feature = "enabled", feature = "derive_former", not( feature = "no_std" ) ) ) ) ] @@ -1075,7 +1056,7 @@ The `child` function within `ParentFormer` is a custom subform setter that plays pub struct Parent { // Use `hint = true` to gennerate sketch of setter. - #[ subform( setter = false, hint = false ) ] + #[ subform_entry( setter = false, hint = false ) ] child : HashMap< String, Child >, } @@ -1091,7 +1072,7 @@ The `child` function within `ParentFormer` is a custom subform setter that plays #[ inline( always ) ] pub fn child( self, name : &str ) -> ChildAsSubformer< Self, impl ChildAsSubformerEnd< Self > > { - self._child_add::< ChildFormer< _ >, _, >() + self._child_subform_entry::< ChildFormer< _ >, _, >() .name( name ) } @@ -1133,27 +1114,27 @@ The `child` function within `ParentFormer` is a custom subform setter that plays # } ``` -Try out `cargo run --example former_custom_subform_setter`. +Try out `cargo run --example former_custom_subform_entry`.
-[See code](./examples/former_custom_subform_setter.rs). +[See code](./examples/former_custom_subform_entry.rs). -## General Container Interface +## General Collection Interface -There are suite of traits designed to abstract and enhance the functionality of container data structures within the forming process. These traits are integral to managing the complexity of container operations, such as adding, modifying, and converting between different representations within containers like vectors, hash maps, etc. They are especially useful when used in conjunction with the `container` attribute in the `former` macro, which automates the implementation of these traits to create robust and flexible builder patterns for complex data structures. +There are suite of traits designed to abstract and enhance the functionality of collection data structures within the forming process. These traits are integral to managing the complexity of collection operations, such as adding, modifying, and converting between different representations within collections like vectors, hash maps, etc. They are especially useful when used in conjunction with the `collection` attribute in the `former` macro, which automates the implementation of these traits to create robust and flexible builder patterns for complex data structures. -- [`Container`] - Defines basic functionalities for containers, managing entries and values, establishing the fundamental operations required for any custom container implementation in forming processes. -- [`EntryToVal`] - Facilitates the conversion of container entries to their value representations, crucial for operations that treat container elements more abstractly as values. -- [`ValToEntry`] - Provides the reverse functionality of `EntryToVal`, converting values back into entries, which is essential for operations that require adding or modifying entries in the container based on value data. -- [`ContainerAdd`] - Adds functionality for inserting entries into a container, considering container-specific rules such as duplication handling and order preservation, enhancing the usability of containers in forming scenarios. -- [`ContainerAssign`] - Extends the container functionality to replace all existing entries with new ones, enabling bulk updates or complete resets of container contents, which is particularly useful in dynamic data environments. +- [`Collection`] - Defines basic functionalities for collections, managing entries and values, establishing the fundamental operations required for any custom collection implementation in forming processes. +- [`EntryToVal`] - Facilitates the conversion of collection entries to their value representations, crucial for operations that treat collection elements more abstractly as values. +- [`ValToEntry`] - Provides the reverse functionality of `EntryToVal`, converting values back into entries, which is essential for operations that require adding or modifying entries in the collection based on value data. +- [`CollectionAdd`] - Adds functionality for inserting entries into a collection, considering collection-specific rules such as duplication handling and order preservation, enhancing the usability of collections in forming scenarios. +- [`CollectionAssign`] - Extends the collection functionality to replace all existing entries with new ones, enabling bulk updates or complete resets of collection contents, which is particularly useful in dynamic data environments. -## Custom Container Former +## Custom Collection Former -Container interface is defined in the crate and implemented for containers like vectors, hash maps, etc, but if you want to use non-standard container you can implement container interface for the container. This example demonstrate how to do that. +Collection interface is defined in the crate and implemented for collections like vectors, hash maps, etc, but if you want to use non-standard collection you can implement collection interface for the collection. This example demonstrate how to do that. -Try out `cargo run --example former_custom_container`. +Try out `cargo run --example former_custom_collection`.
-[See code](./examples/former_custom_container.rs). +[See code](./examples/former_custom_collection.rs). ## Concept of Mutator @@ -1253,6 +1234,110 @@ Try out `cargo run --example former_custom_mutator`.
[See code](./examples/former_custom_mutator.rs). +## Concept of Definitions + +Definitions are utilized to encapsulate and manage generic parameters efficiently and avoid passing each parameter individually. + +Two key definition Traits: + +1. **`FormerDefinitionTypes`**: + - This trait outlines the essential components involved in the formation process, including the types of storage, the form being created, and the context used. It focuses on the types involved rather than the termination of the formation process. +2. **`FormerDefinition`**: + - Building upon `FormerDefinitionTypes`, this trait incorporates the `FormingEnd` callback, linking the formation types with a definitive ending. It specifies how the formation process should conclude, which may involve validations, transformations, or integrations into larger structures. + - The inclusion of the `End` type parameter specifies the end conditions of the formation process, effectively connecting the temporary state held in storage to its ultimate form. + +## Overview of Formation Traits + +The formation process utilizes several core traits, each serving a specific purpose in the lifecycle of entity creation. These traits ensure that entities are constructed methodically, adhering to a structured pattern that enhances maintainability and scalability. Below is a summary of these key traits: + +- `EntityToDefinition`: Links entities to their respective formation definitions which dictate their construction process. +- `EntityToFormer`: Connects entities with formers that are responsible for their step-by-step construction. +- `EntityToStorage`: Specifies the storage structures that temporarily hold the state of an entity during its formation. +- `FormerDefinition`, `FormerDefinitionTypes`: Define the essential properties and ending conditions of the formation process, ensuring entities are formed according to predetermined rules and logic. +- `Storage`: Establishes the fundamental interface for storage types used in the formation process, ensuring each can initialize to a default state. +- `StoragePreform`: Describes the transformation of storage from a mutable, intermediate state into the final, immutable state of the entity, crucial for accurately concluding the formation process. +- `FormerMutator`: Allows for custom mutation logic on the storage and context immediately before the formation process completes, ensuring last-minute adjustments are possible. +- `FormingEnd`: Specifies the closure action at the end of the formation process, which can transform or validate the final state of the entity. +- `FormingEndClosure`: Provides a flexible mechanism for dynamically handling the end of the formation process using closures, useful for complex scenarios. +- `FormerBegin`: Initiates a subforming process, managing how entities begin their formation in terms of storage and context setup. + +These traits collectively facilitate a robust and flexible builder pattern that supports complex object creation and configuration scenarios. + +## Example : Custom Definition + +Define a custom former definition and custom forming logic, and apply them to a collection. + +The example showcases how to accumulate elements into a collection and then transform them into a single result using a custom `FormingEnd` implementation. This pattern is useful for scenarios where the formation process involves aggregation or transformation of input elements into a different type or form. + +```rust +# #[ cfg( any( not( feature = "derive_former" ), not( feature = "enabled" ) ) ) ] +# fn main() {} + +# #[ cfg( all( feature = "derive_former", feature = "enabled" ) ) ] +# fn main() +# { + + // Define a struct `Sum` that will act as a custom former definition. + struct Sum; + + // Implement `FormerDefinitionTypes` for `Sum`. + // This trait defines the types used during the forming process. + impl former::FormerDefinitionTypes for Sum + { + type Storage = Vec; // Collection for the integers. + type Formed = i32; // The final type after forming, which is a single integer. + type Context = (); // No additional context is used in this example. + } + + // Implement `FormerMutator` for `Sum`. + // This trait could include custom mutation logic applied during the forming process, but it's empty in this example. + impl former::FormerMutator for Sum + { + } + + // Implement `FormerDefinition` for `Sum`. + // This trait links the custom types to the former. + impl former::FormerDefinition for Sum + { + type Types = Sum; // Associate the `FormerDefinitionTypes` with `Sum`. + type End = Sum; // Use `Sum` itself as the end handler. + type Storage = Vec; // Specify the storage type. + type Formed = i32; // Specify the final formed type. + type Context = (); // Specify the context type, not used here. + } + + // Implement `FormingEnd` for `Sum`. + // This trait handles the final step of the forming process. + impl former::FormingEnd for Sum + { + fn call + ( + &self, + storage: < Sum as former::FormerDefinitionTypes >::Storage, + _context: Option< < Sum as former::FormerDefinitionTypes >::Context> + ) + -> < Sum as former::FormerDefinitionTypes >::Formed + { + // Sum all integers in the storage vector. + storage.iter().sum() + } + } + + // Use the custom `Former` to sum a list of integers. + let got = former::CollectionFormer::::new(Sum) + .add( 1 ) // Add an integer to the storage. + .add( 2 ) // Add another integer. + .add( 10 ) // Add another integer. + .form(); // Perform the form operation, which triggers the summing logic. + let exp = 13; // Expected result after summing 1, 2, and 10. + assert_eq!(got, exp); // Assert the result is as expected. + + dbg!(got); // Debug print the result to verify the output. + // > got = 13 + +# } +``` + ## Index of Examples @@ -1262,7 +1347,7 @@ Try out `cargo run --example former_custom_mutator`. - [Custom Defaults](./examples/former_custom_defaults.rs) - Former allows the specification of custom default values for fields through the `former( default )` attribute. -- [Custom Definition](./examples/former_custom_definition.rs) - Define a custom former definition and custom forming logic, and apply them to a container. +- [Custom Definition](./examples/former_custom_definition.rs) - Define a custom former definition and custom forming logic, and apply them to a collection. diff --git a/module/core/former/examples/former_container_hashmap.rs b/module/core/former/examples/former_collection_hashmap.rs similarity index 88% rename from module/core/former/examples/former_container_hashmap.rs rename to module/core/former/examples/former_collection_hashmap.rs index 8908adc7ab..4699ec192e 100644 --- a/module/core/former/examples/former_container_hashmap.rs +++ b/module/core/former/examples/former_collection_hashmap.rs @@ -1,5 +1,5 @@ //! -//! This example demonstrates how to effectively employ the `Former` trait to configure a `HashMap` using a container setter. +//! This example demonstrates how to effectively employ the `Former` trait to configure a `HashMap` using a collection setter. //! #[ cfg( not( all( feature = "enabled", feature = "derive_former", not( feature = "no_std" ) ) ) ) ] @@ -12,7 +12,7 @@ fn main() #[ derive( Debug, PartialEq, former::Former ) ] pub struct StructWithMap { - #[ container ] + #[ subform_collection ] map : HashMap< &'static str, &'static str >, } diff --git a/module/core/former/examples/former_container_hashset.rs b/module/core/former/examples/former_collection_hashset.rs similarity index 96% rename from module/core/former/examples/former_container_hashset.rs rename to module/core/former/examples/former_collection_hashset.rs index 2c76d24a0a..7b2822c944 100644 --- a/module/core/former/examples/former_container_hashset.rs +++ b/module/core/former/examples/former_collection_hashset.rs @@ -12,7 +12,7 @@ fn main() #[ derive( Debug, PartialEq, former::Former ) ] pub struct StructWithSet { - #[ container ] + #[ subform_collection ] set : HashSet< &'static str >, } diff --git a/module/core/former/examples/former_container_vector.rs b/module/core/former/examples/former_collection_vector.rs similarity index 86% rename from module/core/former/examples/former_container_vector.rs rename to module/core/former/examples/former_collection_vector.rs index 92f67dbd47..ed813604f8 100644 --- a/module/core/former/examples/former_container_vector.rs +++ b/module/core/former/examples/former_collection_vector.rs @@ -1,5 +1,5 @@ //! -//! This example demonstrates how to employ the `Former` trait to configure a `Vec` using a container setter in a structured manner. +//! This example demonstrates how to employ the `Former` trait to configure a `Vec` using a collection setter in a structured manner. //! #[ cfg( not( all( feature = "enabled", feature = "derive_former", not( feature = "no_std" ) ) ) ) ] @@ -11,7 +11,7 @@ fn main() #[ derive( Debug, PartialEq, former::Former ) ] pub struct StructWithVec { - #[ container ] + #[ subform_collection ] vec : Vec< &'static str >, } diff --git a/module/core/former/examples/former_custom_container.rs b/module/core/former/examples/former_custom_collection.rs similarity index 84% rename from module/core/former/examples/former_custom_container.rs rename to module/core/former/examples/former_custom_collection.rs index c3e9ff0f8b..d30d3a01cb 100644 --- a/module/core/former/examples/former_custom_container.rs +++ b/module/core/former/examples/former_custom_collection.rs @@ -1,8 +1,8 @@ -//! Example former_custom_container.rs +//! Example former_custom_collection.rs //! -//! This example demonstrates how to define and use a custom container with former. -//! The custom container implemented here is a `LoggingSet`, which extends the basic `HashSet` behavior -//! by logging each addition. This example illustrates how to integrate such custom containers with the +//! This example demonstrates how to define and use a custom collection with former. +//! The custom collection implemented here is a `LoggingSet`, which extends the basic `HashSet` behavior +//! by logging each addition. This example illustrates how to integrate such custom collections with the //! Former trait system for use in structured data types. #[ cfg( not( all( feature = "enabled", feature = "derive_former", not( feature = "no_std" ) ) ) ) ] @@ -12,7 +12,7 @@ fn main() { use collection_tools::HashSet; - // Custom container that logs additions. + // Custom collection that logs additions. #[ derive( Debug, PartialEq ) ] pub struct LoggingSet< K > where @@ -21,7 +21,7 @@ fn main() set : HashSet< K >, // Internal HashSet to store the elements. } - // Implement default for the custom container. + // Implement default for the custom collection. impl< K > Default for LoggingSet< K > where K : core::cmp::Eq + core::hash::Hash, @@ -36,7 +36,7 @@ fn main() } } - // Allow the custom container to be converted into an iterator, to iterate over the elements. + // Allow the custom collection to be converted into an iterator, to iterate over the elements. impl< K > IntoIterator for LoggingSet< K > where K : std::cmp::Eq + std::hash::Hash, @@ -64,8 +64,8 @@ fn main() } } - // Implement the Container trait to integrate with the former system. - impl< K > former::Container for LoggingSet< K > + // Implement the Collection trait to integrate with the former system. + impl< K > former::Collection for LoggingSet< K > where K : core::cmp::Eq + core::hash::Hash, { @@ -79,8 +79,8 @@ fn main() } } - // Implement ContainerAdd to handle adding elements to the custom container. - impl< K > former::ContainerAdd for LoggingSet< K > + // Implement CollectionAdd to handle adding elements to the custom collection. + impl< K > former::CollectionAdd for LoggingSet< K > where K : core::cmp::Eq + core::hash::Hash, { @@ -91,8 +91,8 @@ fn main() } } - // Implement ContainerAssign to handle bulk assignment of elements. - impl< K > former::ContainerAssign for LoggingSet< K > + // Implement CollectionAssign to handle bulk assignment of elements. + impl< K > former::CollectionAssign for LoggingSet< K > where K : core::cmp::Eq + core::hash::Hash, { @@ -106,8 +106,8 @@ fn main() } } - // Implement ContainerValToEntry to convert values back to entries. - impl< K > former::ContainerValToEntry< K > for LoggingSet< K > + // Implement CollectionValToEntry to convert values back to entries. + impl< K > former::CollectionValToEntry< K > for LoggingSet< K > where K : core::cmp::Eq + core::hash::Hash, { @@ -121,7 +121,7 @@ fn main() // = storage - // Define storage behavior for the custom container. + // Define storage behavior for the custom collection. impl< K > former::Storage for LoggingSet< K > where @@ -138,13 +138,13 @@ fn main() { fn preform( self ) -> Self::Preformed { - self // Return the container as is. + self // Return the collection as is. } } // = definition types - // Definitions related to the type settings for the LoggingSet, which detail how the container should behave with former. + // Definitions related to the type settings for the LoggingSet, which detail how the collection should behave with former. /// Holds generic parameter types for forming operations related to `LoggingSet`. #[ derive( Debug, Default ) ] @@ -249,17 +249,17 @@ fn main() // = subformer - // Subformer type alias simplifies the usage of `ContainerFormer` with `LoggingSet`. + // Subformer type alias simplifies the usage of `CollectionFormer` with `LoggingSet`. pub type LoggingSetAsSubformer< K, Context, Formed, End > = - former::ContainerFormer::< K, LoggingSetDefinition< K, Context, Formed, End > >; + former::CollectionFormer::< K, LoggingSetDefinition< K, Context, Formed, End > >; - // == use custom container + // == use custom collection /// Parent required for the template. #[ derive( Debug, Default, PartialEq, former::Former ) ] pub struct Parent { - #[ container ] + #[ subform_collection ] children : LoggingSet< i32 >, } diff --git a/module/core/former/examples/former_custom_container_setter.rs b/module/core/former/examples/former_custom_container_setter.rs deleted file mode 100644 index d5565a0908..0000000000 --- a/module/core/former/examples/former_custom_container_setter.rs +++ /dev/null @@ -1,91 +0,0 @@ -// Example former_custom_container_setter.rs - -//! -//! This example demonstrates the use of container setters to manage complex nested data structures with the `Former` trait, focusing on a parent-child relationship structured around a container `HashMap`. Unlike typical builder patterns that add individual elements using subform setters, this example uses a container setter to manage the entire collection of children. -//! -//! The `child` function within `ParentFormer` is a custom subform setter that plays a crucial role. It uniquely employs the `ChildFormer` to add and configure children by their names within the parent's builder pattern. This method demonstrates a powerful technique for integrating subformers that manage specific elements of a container—each child entity in this case. -//! -//! #### Types of Setters -//! -//! It's crucial to understand the differences among subform setters, container setters, and scalar setters: -//! -//! - **Scalar Setter**: Directly sets scalar values or simple fields within the forming entity. Unlike subform or container setters that manage complex objects or collections, scalar setters handle basic data types or individual fields. These are typically straightforward setter methods that do not involve nested formers or additional structuring. -//! -//! - **Container Setter**: Returns a former of the container itself, offering an interface to manage the container as a whole rather than its individual elements. This type of setter is useful for applying configurations or validations to the entire collection, such as a `HashMap` of children. -//! -//! - **Subform Setter**: Returns a former of an element within a container, providing an interface to individually form each element. For example, the `child` method acts as a subform setter, allowing for the addition and configuration of individual `Child` entities within the `Parent`'s `HashMap`. -//! -//! Each type of setter is designed to address different needs in the formation process, ensuring that users can build complex, nested structures or simply set individual field values as required. -//! - -// Ensure the example only compiles when the appropriate features are enabled. -#[ cfg( not( all( feature = "enabled", feature = "derive_former", not( feature = "no_std" ) ) ) ) ] -fn main() {} -#[ cfg( all( feature = "enabled", feature = "derive_former", not( feature = "no_std" ) ) ) ] -fn main() -{ - use collection_tools::HashMap; - use former::Former; - - // Child struct with Former derived for builder pattern support - #[ derive( Debug, PartialEq, Former ) ] - // Use `#[ debug ]` to expand and debug generate code. - // #[ debug ] - pub struct Child - { - name : String, - description : String, - } - - // Parent struct to hold children - #[ derive( Debug, PartialEq, Former ) ] - // Use `#[ debug ]` to expand and debug generate code. - // #[ debug ] - pub struct Parent - { - // Use `hint = true` to gennerate sketch of setter. - #[ container( setter = false, hint = false ) ] - children : HashMap< String, Child >, - } - - /// The containr setter provides a container setter that returns a ContainerFormer tailored for managing a collection of child entities. It employs a generic container definition to facilitate operations on the entire collection, such as adding or updating elements. - impl< Definition, > ParentFormer< Definition, > - where - Definition : former::FormerDefinition< Storage = ParentFormerStorage >, - { - - #[ inline( always ) ] - pub fn children( self ) -> former::ContainerFormer:: - < - ( String, Child ), - former::HashMapDefinition< String, Child, Self, Self, ParentFormerAssignChildrenEnd< Definition >, > - > - { - self._children_container_former() - } - - } - - let echo = Child { name : "echo".to_string(), description : "prints all subjects and properties".to_string() }; - let exit = Child { name : "exit".to_string(), description : "just exit".to_string() }; - let ca = Parent::former() - .children() - .add( ( echo.name.clone(), echo ) ) - .add( ( exit.name.clone(), exit ) ) - .end() - .form(); - - dbg!( &ca ); - // > &ca = Parent { - // > child: { - // > "echo": Child { - // > name: "echo", - // > description: "prints all subjects and properties", - // > }, - // > "exit": Child { - // > name: "exit", - // > description: "just exit", - // > }, - // > }, - // > } -} diff --git a/module/core/former/examples/former_custom_definition.rs b/module/core/former/examples/former_custom_definition.rs index 40957cf3ce..6b3ef3e978 100644 --- a/module/core/former/examples/former_custom_definition.rs +++ b/module/core/former/examples/former_custom_definition.rs @@ -1,8 +1,8 @@ //! ## Example : Custom Definition //! -//! Define a custom former definition and custom forming logic, and apply them to a container. +//! Define a custom former definition and custom forming logic, and apply them to a collection. //! -//! The example showcases how to accumulate elements into a container and then transform them into a single result +//! The example showcases how to accumulate elements into a collection and then transform them into a single result //! using a custom `FormingEnd` implementation. This pattern is useful for scenarios where the formation process //! involves aggregation or transformation of input elements into a different type or form. @@ -19,7 +19,7 @@ fn main() // This trait defines the types used during the forming process. impl former::FormerDefinitionTypes for Sum { - type Storage = Vec; // Container for the integers. + type Storage = Vec; // Collection for the integers. type Formed = i32; // The final type after forming, which is a single integer. type Context = (); // No additional context is used in this example. } @@ -59,7 +59,7 @@ fn main() } // Use the custom `Former` to sum a list of integers. - let got = former::ContainerFormer::::new(Sum) + let got = former::CollectionFormer::::new(Sum) .add( 1 ) // Add an integer to the storage. .add( 2 ) // Add another integer. .add( 10 ) // Add another integer. diff --git a/module/core/former/examples/former_custom_scalar_setter.rs b/module/core/former/examples/former_custom_scalar_setter.rs index e5acb1847b..bd74f8640f 100644 --- a/module/core/former/examples/former_custom_scalar_setter.rs +++ b/module/core/former/examples/former_custom_scalar_setter.rs @@ -4,19 +4,21 @@ //! //! Use of a scalar setter within a `Former` trait implementation to directly assign a `HashMap` of `Child` entities to a `Parent` structure using a custom setter function. //! -//! Unlike the more complex subform and container setters shown in previous examples, this example focuses on a straightforward approach to directly set a scalar value within a parent entity. The `Parent` struct manages a `HashMap` of `Child` entities, and the scalar setter is used to set the entire `HashMap` directly. The `child` function within `ParentFormer` is a custom subform setter that plays a crucial role. It uniquely employs the `ChildFormer` to add and configure children by their names within the parent's builder pattern. This method demonstrates a powerful technique for integrating subformers that manage specific elements of a container—each child entity in this case. +//! Unlike the more complex subform and collection setters shown in previous examples, this example focuses on a straightforward approach to directly set a scalar value within a parent entity. The `Parent` struct manages a `HashMap` of `Child` entities, and the scalar setter is used to set the entire `HashMap` directly. The `child` function within `ParentFormer` is a custom subform setter that plays a crucial role. It uniquely employs the `ChildFormer` to add and configure children by their names within the parent's builder pattern. This method demonstrates a powerful technique for integrating subformers that manage specific elements of a collection—each child entity in this case. //! -//! #### Types of Setters +//! #### Types of Setters / Subformers //! -//! It's crucial to understand the differences among subform setters, container setters, and scalar setters: +//! Understanding the distinctions among the types of setters or subformers is essential for effectively employing the builder pattern in object construction. Each type of setter is designed to meet specific needs in building complex, structured data entities: //! -//! - **Scalar Setter**: Directly sets scalar values or simple fields within the forming entity. Unlike subform or container setters that manage complex objects or collections, scalar setters handle basic data types or individual fields. These are typically straightforward setter methods that do not involve nested formers or additional structuring. +//! - **Scalar Setter**: Handles the direct assignment of scalar values or simple fields within an entity. These setters manage basic data types or individual fields and do not involve nested formers or complex structuring. //! -//! - **Container Setter**: Returns a former of the container itself, offering an interface to manage the container as a whole rather than its individual elements. This type of setter is useful for applying configurations or validations to the entire collection, such as a `HashMap` of children. +//! - **Subform Collection Setter**: Facilitates the management of a collection as a whole by returning a former that provides an interface to configure the entire collection. This setter is beneficial for applying uniform configurations or validations to all elements in a collection, such as a `HashMap` of children. //! -//! - **Subform Setter**: Returns a former of an element within a container, providing an interface to individually form each element. For example, the `child` method acts as a subform setter, allowing for the addition and configuration of individual `Child` entities within the `Parent`'s `HashMap`. +//! - **Subform Entry Setter**: This setter allows for the individual formation of elements within a collection. It returns a former for each element, enabling detailed configuration and addition of complex elements within collections, exemplified by managing `Child` entities within a `Parent`'s `HashMap`. //! -//! Each type of setter is designed to address different needs in the formation process, ensuring that users can build complex, nested structures or simply set individual field values as required. +//! - **Subform Scalar Setter**: Similar to the subform entry setter but designed for scalar fields that have a former implementation. This setter does not collect instances into a collection because there is no collection involved, only a scalar field. It is used when the scalar field itself needs to be configured or modified through its dedicated former. +//! +//! These setters ensure that developers can precisely and efficiently set properties, manage collections, and configure complex structures within their applications. //! #[ cfg( not( all( feature = "enabled", feature = "derive_former", not( feature = "no_std" ) ) ) ) ] diff --git a/module/core/former/examples/former_custom_setter_overriden.rs b/module/core/former/examples/former_custom_setter_overriden.rs index 4723ab16e2..08acd738a0 100644 --- a/module/core/former/examples/former_custom_setter_overriden.rs +++ b/module/core/former/examples/former_custom_setter_overriden.rs @@ -1,3 +1,6 @@ +//! +//! ## Example : Custom Setter Overriding +//! //! It's also possible to completely override setter and write its own from scratch. //! //! For that use attribe `[ setter( false ) ]` to disable setter. In the example, the default setter for `word` is disabled, and a custom setter is defined to automatically append an exclamation mark to the string. This method allows for complete control over the data assignment process, enabling the inclusion of any necessary logic or validation steps. @@ -15,25 +18,34 @@ fn main() #[ derive( Debug, Former ) ] pub struct StructWithCustomSetters { - #[ scalar( setter = false ) ] + // Use `hint = true` to gennerate sketch of setter. + #[ scalar( setter = false, hint = false ) ] word : String, } - impl StructWithCustomSettersFormer + impl< Definition > StructWithCustomSettersFormer< Definition > + where + Definition : former::FormerDefinition< Storage = StructWithCustomSettersFormerStorage >, { - // Custom alternative setter for `word` - pub fn word( mut self, value : impl Into< String > ) -> Self + #[ inline ] + pub fn word< Src >( mut self, src : Src ) -> Self + where + Src : ::core::convert::Into< String >, { debug_assert!( self.storage.word.is_none() ); - self.storage.word = Some( format!( "{}!", value.into() ) ); + self.storage.word = Some( format!( "{}!", src.into() ) ); self } - } let example = StructWithCustomSetters::former() .word( "Hello" ) .form(); assert_eq!( example.word, "Hello!".to_string() ); + dbg!( example ); + //> StructWithCustomSetters { + //> word: "Hello!", + //> } + } diff --git a/module/core/former/examples/former_custom_subform_collection.rs b/module/core/former/examples/former_custom_subform_collection.rs new file mode 100644 index 0000000000..0fdb14e674 --- /dev/null +++ b/module/core/former/examples/former_custom_subform_collection.rs @@ -0,0 +1,95 @@ +// Example former_custom_subform_collection.rs + +//! +//! ## Example : Custom Subform Collection Setter +//! +//! This example demonstrates the use of collection setters to manage complex nested data structures with the `Former` trait, focusing on a parent-child relationship structured around a collection `HashMap`. Unlike typical builder patterns that add individual elements using subform setters, this example uses a collection setter to manage the entire collection of children. +//! +//! The `child` function within `ParentFormer` is a custom subform setter that plays a crucial role. It uniquely employs the `ChildFormer` to add and configure children by their names within the parent's builder pattern. This method demonstrates a powerful technique for integrating subformers that manage specific elements of a collection—each child entity in this case. +//! +//! #### Types of Setters / Subformers +//! +//! Understanding the distinctions among the types of setters or subformers is essential for effectively employing the builder pattern in object construction. Each type of setter is designed to meet specific needs in building complex, structured data entities: +//! +//! - **Scalar Setter**: Handles the direct assignment of scalar values or simple fields within an entity. These setters manage basic data types or individual fields and do not involve nested formers or complex structuring. +//! +//! - **Subform Collection Setter**: Facilitates the management of a collection as a whole by returning a former that provides an interface to configure the entire collection. This setter is beneficial for applying uniform configurations or validations to all elements in a collection, such as a `HashMap` of children. +//! +//! - **Subform Entry Setter**: This setter allows for the individual formation of elements within a collection. It returns a former for each element, enabling detailed configuration and addition of complex elements within collections, exemplified by managing `Child` entities within a `Parent`'s `HashMap`. +//! +//! - **Subform Scalar Setter**: Similar to the subform entry setter but designed for scalar fields that have a former implementation. This setter does not collect instances into a collection because there is no collection involved, only a scalar field. It is used when the scalar field itself needs to be configured or modified through its dedicated former. +//! +//! These setters ensure that developers can precisely and efficiently set properties, manage collections, and configure complex structures within their applications. +//! + +// Ensure the example only compiles when the appropriate features are enabled. +#[ cfg( not( all( feature = "enabled", feature = "derive_former", not( feature = "no_std" ) ) ) ) ] +fn main() {} +#[ cfg( all( feature = "enabled", feature = "derive_former", not( feature = "no_std" ) ) ) ] +fn main() +{ + use collection_tools::HashMap; + use former::Former; + + // Child struct with Former derived for builder pattern support + #[ derive( Debug, PartialEq, Former ) ] + // Use `#[ debug ]` to expand and debug generate code. + // #[ debug ] + pub struct Child + { + name : String, + description : String, + } + + // Parent struct to hold children + #[ derive( Debug, PartialEq, Former ) ] + // Use `#[ debug ]` to expand and debug generate code. + // #[ debug ] + pub struct Parent + { + // Use `hint = true` to gennerate sketch of setter. + #[ subform_collection( setter = false, hint = false ) ] + children : HashMap< String, Child >, + } + + /// The containr 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. + impl< Definition, > ParentFormer< Definition, > + where + Definition : former::FormerDefinition< Storage = ParentFormerStorage >, + { + + #[ inline( always ) ] + pub fn children( self ) -> former::CollectionFormer:: + < + ( String, Child ), + former::HashMapDefinition< String, Child, Self, Self, ParentSubformCollectionChildrenEnd< Definition >, > + > + { + self._children_subform_collection() + } + + } + + let echo = Child { name : "echo".to_string(), description : "prints all subjects and properties".to_string() }; + let exit = Child { name : "exit".to_string(), description : "just exit".to_string() }; + let ca = Parent::former() + .children() + .add( ( echo.name.clone(), echo ) ) + .add( ( exit.name.clone(), exit ) ) + .end() + .form(); + + dbg!( &ca ); + // > &ca = Parent { + // > child: { + // > "echo": Child { + // > name: "echo", + // > description: "prints all subjects and properties", + // > }, + // > "exit": Child { + // > name: "exit", + // > description: "just exit", + // > }, + // > }, + // > } +} diff --git a/module/core/former/examples/former_custom_subform_setter.rs b/module/core/former/examples/former_custom_subform_entry.rs similarity index 62% rename from module/core/former/examples/former_custom_subform_setter.rs rename to module/core/former/examples/former_custom_subform_entry.rs index bff35ac6ea..f035ea53a6 100644 --- a/module/core/former/examples/former_custom_subform_setter.rs +++ b/module/core/former/examples/former_custom_subform_entry.rs @@ -1,21 +1,24 @@ -// Example former_custom_subformer.rs +// Example former_custom_subform_entry.rs +//! ## Example : Custom Subform Entry Setter //! //! This example illustrates the implementation of nested builder patterns using the `Former` trait, emphasizing a parent-child relationship. Here, the `Parent` struct utilizes `ChildFormer` as a custom subformer to dynamically manage its `child` field—a `HashMap`. Each child in the `HashMap` is uniquely identified and configured via the `ChildFormer`. //! -//! The `child` function within `ParentFormer` is a custom subform setter that plays a crucial role. It uniquely employs the `ChildFormer` to add and configure children by their names within the parent's builder pattern. This method demonstrates a powerful technique for integrating subformers that manage specific elements of a container—each child entity in this case. +//! The `child` function within `ParentFormer` is a custom subform setter that plays a crucial role. It uniquely employs the `ChildFormer` to add and configure children by their names within the parent's builder pattern. This method demonstrates a powerful technique for integrating subformers that manage specific elements of a collection—each child entity in this case. //! -//! #### Types of Setters +//! #### Types of Setters / Subformers //! -//! It's crucial to understand the differences among subform setters, container setters, and scalar setters: +//! Understanding the distinctions among the types of setters or subformers is essential for effectively employing the builder pattern in object construction. Each type of setter is designed to meet specific needs in building complex, structured data entities: //! -//! - **Scalar Setter**: Directly sets scalar values or simple fields within the forming entity. Unlike subform or container setters that manage complex objects or collections, scalar setters handle basic data types or individual fields. These are typically straightforward setter methods that do not involve nested formers or additional structuring. +//! - **Scalar Setter**: Handles the direct assignment of scalar values or simple fields within an entity. These setters manage basic data types or individual fields and do not involve nested formers or complex structuring. //! -//! - **Container Setter**: Returns a former of the container itself, offering an interface to manage the container as a whole rather than its individual elements. This type of setter is useful for applying configurations or validations to the entire collection, such as a `HashMap` of children. +//! - **Subform Collection Setter**: Facilitates the management of a collection as a whole by returning a former that provides an interface to configure the entire collection. This setter is beneficial for applying uniform configurations or validations to all elements in a collection, such as a `HashMap` of children. //! -//! - **Subform Setter**: Returns a former of an element within a container, providing an interface to individually form each element. For example, the `child` method acts as a subform setter, allowing for the addition and configuration of individual `Child` entities within the `Parent`'s `HashMap`. +//! - **Subform Entry Setter**: This setter allows for the individual formation of elements within a collection. It returns a former for each element, enabling detailed configuration and addition of complex elements within collections, exemplified by managing `Child` entities within a `Parent`'s `HashMap`. //! -//! Each type of setter is designed to address different needs in the formation process, ensuring that users can build complex, nested structures or simply set individual field values as required. +//! - **Subform Scalar Setter**: Similar to the subform entry setter but designed for scalar fields that have a former implementation. This setter does not collect instances into a collection because there is no collection involved, only a scalar field. It is used when the scalar field itself needs to be configured or modified through its dedicated former. +//! +//! These setters ensure that developers can precisely and efficiently set properties, manage collections, and configure complex structures within their applications. //! #[ cfg( not( all( feature = "enabled", feature = "derive_former", not( feature = "no_std" ) ) ) ) ] @@ -45,7 +48,7 @@ fn main() pub struct Parent { // Use `hint = true` to gennerate sketch of setter. - #[ subform( setter = false, hint = false ) ] + #[ subform_entry( setter = false, hint = false ) ] child : HashMap< String, Child >, } @@ -61,7 +64,7 @@ fn main() #[ inline( always ) ] pub fn child( self, name : &str ) -> ChildAsSubformer< Self, impl ChildAsSubformerEnd< Self > > { - self._child_add::< ChildFormer< _ >, _, >() + self._child_subform_entry::< ChildFormer< _ >, _, >() .name( name ) } diff --git a/module/core/former/examples/former_custom_subform_setter2.rs b/module/core/former/examples/former_custom_subform_entry2.rs similarity index 71% rename from module/core/former/examples/former_custom_subform_setter2.rs rename to module/core/former/examples/former_custom_subform_entry2.rs index 7c781d6128..545adfe7f4 100644 --- a/module/core/former/examples/former_custom_subform_setter2.rs +++ b/module/core/former/examples/former_custom_subform_entry2.rs @@ -1,23 +1,25 @@ // Example former_custom_subformer2.rs //! -//! This example extends the demonstration of nested builder patterns using the `Former` trait, highlighting a parent-child relationship similar to the `former_custom_subformer.rs`. However, this variant, `former_custom_subformer2.rs`, showcases a more flexible but complex approach to managing the `child` field in the `Parent` struct—a `HashMap` of `Child` entities. Instead of relying on a predefined subformer setter (`_child_add`), this example constructs the subformer logic directly using closures. This method provides greater control over how children are added and managed within the `Parent`. +//! This example extends the demonstration of nested builder patterns using the `Former` trait, highlighting a parent-child relationship similar to the `former_custom_subformer.rs`. However, this variant, `former_custom_subformer2.rs`, showcases a more flexible but complex approach to managing the `child` field in the `Parent` struct—a `HashMap` of `Child` entities. Instead of relying on a predefined subformer setter (`_child_subform_entry`), this example constructs the subformer logic directly using closures. This method provides greater control over how children are added and managed within the `Parent`. //! //! #### Custom Subform Setter //! -//! The `child` function within `ParentFormer` is a custom subform setter that plays a crucial role. It uniquely employs the `ChildFormer` to add and configure children by their names within the parent's builder pattern. This method demonstrates a powerful technique for integrating subformers that manage specific elements of a container—each child entity in this case. +//! The `child` function within `ParentFormer` is a custom subform setter that plays a crucial role. It uniquely employs the `ChildFormer` to add and configure children by their names within the parent's builder pattern. This method demonstrates a powerful technique for integrating subformers that manage specific elements of a collection—each child entity in this case. //! -//! #### Types of Setters +//! #### Types of Setters / Subformers //! -//! It's crucial to understand the differences among subform setters, container setters, and scalar setters: +//! Understanding the distinctions among the types of setters or subformers is essential for effectively employing the builder pattern in object construction. Each type of setter is designed to meet specific needs in building complex, structured data entities: //! -//! - **Scalar Setter**: Directly sets scalar values or simple fields within the forming entity. Unlike subform or container setters that manage complex objects or collections, scalar setters handle basic data types or individual fields. These are typically straightforward setter methods that do not involve nested formers or additional structuring. +//! - **Scalar Setter**: Handles the direct assignment of scalar values or simple fields within an entity. These setters manage basic data types or individual fields and do not involve nested formers or complex structuring. //! -//! - **Container Setter**: Returns a former of the container itself, offering an interface to manage the container as a whole rather than its individual elements. This type of setter is useful for applying configurations or validations to the entire collection, such as a `HashMap` of children. +//! - **Subform Collection Setter**: Facilitates the management of a collection as a whole by returning a former that provides an interface to configure the entire collection. This setter is beneficial for applying uniform configurations or validations to all elements in a collection, such as a `HashMap` of children. //! -//! - **Subform Setter**: Returns a former of an element within a container, providing an interface to individually form each element. For example, the `child` method acts as a subform setter, allowing for the addition and configuration of individual `Child` entities within the `Parent`'s `HashMap`. +//! - **Subform Entry Setter**: This setter allows for the individual formation of elements within a collection. It returns a former for each element, enabling detailed configuration and addition of complex elements within collections, exemplified by managing `Child` entities within a `Parent`'s `HashMap`. //! -//! Each type of setter is designed to address different needs in the formation process, ensuring that users can build complex, nested structures or simply set individual field values as required. +//! - **Subform Scalar Setter**: Similar to the subform entry setter but designed for scalar fields that have a former implementation. This setter does not collect instances into a collection because there is no collection involved, only a scalar field. It is used when the scalar field itself needs to be configured or modified through its dedicated former. +//! +//! These setters ensure that developers can precisely and efficiently set properties, manage collections, and configure complex structures within their applications. //! // Ensure the example only compiles when the appropriate features are enabled. @@ -46,7 +48,7 @@ fn main() pub struct Parent { // Use `hint = true` to gennerate sketch of setter. - #[ subform( setter = false, hint = false ) ] + #[ subform_entry( setter = false, hint = false ) ] child : HashMap< String, Child >, } @@ -73,7 +75,7 @@ fn main() super_former.storage.child = Some( Default::default() ); } - // add instance to the container + // add instance to the collection super_former.storage.child.as_mut().unwrap() .entry( preformed.name.clone() ) .or_insert( preformed.clone() ); @@ -85,7 +87,7 @@ fn main() } /// Dynamically adds named child entities to the `Parent` structure using a custom subformer. - /// Unlike traditional methods that might use predefined setters like `_child_add`, this function + /// Unlike traditional methods that might use predefined setters like `_child_subform_entry`, this function /// explicitly constructs a subformer setup through a closure to provide greater flexibility and control. /// #[ inline( always ) ] @@ -101,12 +103,12 @@ fn main() super_former.storage.child = Some( Default::default() ); } - // add instance to the container + // add instance to the collection super_former.storage.child.as_mut().unwrap() .entry( preformed.name.clone() ) .or_insert( preformed.clone() ); - // custom logic to add two instances to the container + // custom logic to add two instances to the collection super_former.storage.child.as_mut().unwrap() .entry( format!( "{}_2", preformed.name ) ) .or_insert( preformed.clone() ); diff --git a/module/core/former/examples/former_custom_subform_scalar.rs b/module/core/former/examples/former_custom_subform_scalar.rs new file mode 100644 index 0000000000..b63f9e2d1d --- /dev/null +++ b/module/core/former/examples/former_custom_subform_scalar.rs @@ -0,0 +1,88 @@ +// Example former_custom_subform_scalar.rs + +//! +//! ## Example : Custom Subform Scalar Setter +//! +//! Implementation of a custom subform scalar setter using the `Former` trait in Rust. +//! +//! This example focuses on the usage of a subform scalar setter to manage complex scalar types within a parent structure. +//! Unlike more general subform setters that handle collections, this setter specifically configures scalar fields that have +//! their own formers, allowing for detailed configuration within a nested builder pattern. +//! +//! #### Types of Setters / Subformers +//! +//! Understanding the distinctions among the types of setters or subformers is essential for effectively employing the builder pattern in object construction. Each type of setter is designed to meet specific needs in building complex, structured data entities: +//! +//! - **Scalar Setter**: Handles the direct assignment of scalar values or simple fields within an entity. These setters manage basic data types or individual fields and do not involve nested formers or complex structuring. +//! +//! - **Subform Collection Setter**: Facilitates the management of a collection as a whole by returning a former that provides an interface to configure the entire collection. This setter is beneficial for applying uniform configurations or validations to all elements in a collection, such as a `HashMap` of children. +//! +//! - **Subform Entry Setter**: This setter allows for the individual formation of elements within a collection. It returns a former for each element, enabling detailed configuration and addition of complex elements within collections, exemplified by managing `Child` entities within a `Parent`'s `HashMap`. +//! +//! - **Subform Scalar Setter**: Similar to the subform entry setter but designed for scalar fields that have a former implementation. This setter does not collect instances into a collection because there is no collection involved, only a scalar field. It is used when the scalar field itself needs to be configured or modified through its dedicated former. +//! +//! These setters ensure that developers can precisely and efficiently set properties, manage collections, and configure complex structures within their applications. +//! + + +#[ cfg( not( all( feature = "enabled", feature = "derive_former", not( feature = "no_std" ) ) ) ) ] +fn main() +{} + +// Ensures the example only compiles when the appropriate features are enabled. +#[ cfg( all( feature = "enabled", feature = "derive_former", not( feature = "no_std" ) ) ) ] +fn main() +{ + use former::Former; + + // Child struct with Former derived for builder pattern support + #[ derive( Debug, PartialEq, Former ) ] + // Optional: Use `#[debug]` to expand and debug generated code. + // #[debug] + pub struct Child + { + name : String, + description : String, + } + + // Parent struct designed to hold a single Child instance using subform scalar + #[ derive( Debug, PartialEq, Former ) ] + // Optional: Use `#[debug]` to expand and debug generated code. + // #[debug] + pub struct Parent + { + // 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 ) ] + child : Child, + } + + /// Extends `ParentFormer` to include a method that initializes and configures a subformer for the 'child' field. + /// This function demonstrates the dynamic addition of a named child, leveraging a subformer to specify detailed properties. + impl< Definition > ParentFormer< Definition > + where + Definition : former::FormerDefinition< Storage = < Parent as former::EntityToStorage >::Storage >, + { + #[ inline( always ) ] + pub fn child( self, name : &str ) -> ChildAsSubformer< Self, impl ChildAsSubformerEnd< Self > > + { + self._child_subform_scalar::< ChildFormer< _ >, _, >().name( name ) + } + } + + // Creating an instance of `Parent` using the builder pattern to configure `Child` + let ca = Parent::former() + .child( "echo" ) // starts the configuration of the `child` subformer + .description( "prints all subjects and properties" ) // sets additional properties for the `Child` + .end() // finalize the child configuration + .form(); // finalize the Parent configuration + + dbg!( &ca ); // Outputs the structured data for review + // Expected output: + //> Parent { + //> child: Child { + //> name: "echo", + //> description: "prints all subjects and properties", + //> }, + //> } +} diff --git a/module/core/former/src/container.rs b/module/core/former/src/collection.rs similarity index 65% rename from module/core/former/src/container.rs rename to module/core/former/src/collection.rs index 2e0897da73..36ba0b7278 100644 --- a/module/core/former/src/container.rs +++ b/module/core/former/src/collection.rs @@ -1,8 +1,8 @@ //! //! This module defines traits and structures that facilitate the management and manipulation -//! of container data structures within a builder pattern context. It provides a comprehensive -//! interface for adding, managing, and converting elements within various types of containers, -//! such as vectors, hash maps, and custom container implementations. +//! of collection data structures within a builder pattern context. It provides a comprehensive +//! interface for adding, managing, and converting elements within various types of collections, +//! such as vectors, hash maps, and custom collection implementations. //! /// Internal namespace. @@ -11,18 +11,18 @@ pub( crate ) mod private use crate::*; - /// Facilitates the conversion of container entries to their corresponding value representations. + /// Facilitates the conversion of collection entries to their corresponding value representations. /// - /// This trait is utilized to transform an entry of a container into a value, abstracting the operation of containers - /// like vectors or hash maps. It ensures that even in complex container structures, entries can be seamlessly managed + /// This trait is utilized to transform an entry of a collection into a value, abstracting the operation of collections + /// like vectors or hash maps. It ensures that even in complex collection structures, entries can be seamlessly managed /// and manipulated as values. - pub trait EntryToVal< Container > + pub trait EntryToVal< Collection > { - /// The type of values stored in the container. This might be distinct from `Entry` in complex containers. + /// The type of values stored in the collection. This might be distinct from `Entry` in complex collections. /// For example, in a `HashMap`, while `Entry` might be a ( key, value ) tuple, `Val` might only be the value part. type Val; - /// Converts an entry into a value representation specific to the type of container. This conversion is crucial + /// Converts an entry into a value representation specific to the type of collection. This conversion is crucial /// for handling operations on entries, especially when they need to be treated or accessed as individual values, /// such as retrieving the value part from a key-value pair in a hash map. fn entry_to_val( self ) -> Self::Val; @@ -30,7 +30,7 @@ pub( crate ) mod private impl< C, E > EntryToVal< C > for E where - C : Container< Entry = E >, + C : Collection< Entry = E >, { type Val = C::Val; @@ -40,23 +40,23 @@ pub( crate ) mod private } } - /// Provides a mechanism for transforming a value back into a container-specific entry format. + /// Provides a mechanism for transforming a value back into a collection-specific entry format. /// - /// This trait is particularly valuable in scenarios where the operations on a container require + /// This trait is particularly valuable in scenarios where the operations on a collection require /// not just the manipulation of values but also the re-integration of these values as entries. /// It is especially crucial in complex data structures, such as `HashMap`s, where entries /// often involve a key-value pair, and simple values need to be restructured to fit this model /// for operations like insertion or update. - pub trait ContainerValToEntry< Val > + pub trait CollectionValToEntry< Val > { - /// The specific type of entry that corresponds to the value within the container. + /// The specific type of entry that corresponds to the value within the collection. /// For example, in a `HashMap`, this might be a tuple of a key and a value. type Entry; - /// Converts a value into a container-specific entry, facilitating operations that modify - /// the container. This method is key for ensuring that values can be correctly integrated - /// back into the container, particularly when the entry type is more complex than the value. + /// Converts a value into a collection-specific entry, facilitating operations that modify + /// the collection. This method is key for ensuring that values can be correctly integrated + /// back into the collection, particularly when the entry type is more complex than the value. /// /// # Parameters /// * `val` - The value to be converted into an entry. @@ -66,11 +66,11 @@ pub( crate ) mod private /// /// # Example /// ``` - /// use former::ContainerValToEntry; + /// use former::CollectionValToEntry; /// /// struct PairMap; /// - /// impl ContainerValToEntry< ( i32, i32 ) > for PairMap + /// impl CollectionValToEntry< ( i32, i32 ) > for PairMap /// { /// type Entry = ( String, i32 ); /// @@ -83,24 +83,24 @@ pub( crate ) mod private fn val_to_entry( val : Val ) -> Self::Entry; } - /// Facilitates the conversion of values back into entries for specific container types. + /// Facilitates the conversion of values back into entries for specific collection types. /// - /// This trait wraps the functionality of `ContainerValToEntry`, providing a more ergonomic + /// This trait wraps the functionality of `CollectionValToEntry`, providing a more ergonomic /// interface for converting values directly within the type they pertain to. It is useful - /// in maintaining the integrity of container operations, especially when dealing with + /// in maintaining the integrity of collection operations, especially when dealing with /// sophisticated structures that separate the concept of values and entries, such as `HashMap`s - /// and other associative containers. - pub trait ValToEntry< Container > + /// and other associative collections. + pub trait ValToEntry< Collection > { - /// Represents the type of entry that corresponds to the value within the container. + /// Represents the type of entry that corresponds to the value within the collection. type Entry; - /// Transforms the instance (value) into an entry compatible with the specified container. - /// This conversion is essential for operations like insertion or modification within the container, + /// Transforms the instance (value) into an entry compatible with the specified collection. + /// This conversion is essential for operations like insertion or modification within the collection, /// where the value needs to be formatted as an entry. /// /// # Returns - /// Returns the entry constructed from the instance of the value, ready for integration into the container. + /// Returns the entry constructed from the instance of the value, ready for integration into the collection. /// /// # Example /// ``` @@ -123,60 +123,60 @@ pub( crate ) mod private impl< C, Val > ValToEntry< C > for Val where - C : ContainerValToEntry< Val >, + C : CollectionValToEntry< Val >, { type Entry = C::Entry; - /// Invokes the `val_to_entry` function of the `ContainerValToEntry` trait to convert the value to an entry. + /// Invokes the `val_to_entry` function of the `CollectionValToEntry` trait to convert the value to an entry. fn val_to_entry( self ) -> C::Entry { C::val_to_entry( self ) } } - /// Represents a container by defining the types of entries and values it handles. + /// Represents a collection by defining the types of entries and values it handles. /// - /// This trait abstracts the nature of containers in data structures, facilitating the handling of contained - /// entries and values, especially in scenarios where the structure of the container allows for complex relationships, - /// such as `HashMap`s. It not only identifies what constitutes an entry and a value in the context of the container + /// This trait abstracts the nature of collections in data structures, facilitating the handling of contained + /// entries and values, especially in scenarios where the structure of the collection allows for complex relationships, + /// such as `HashMap`s. It not only identifies what constitutes an entry and a value in the context of the collection /// but also provides utility for converting between these two, which is critical in operations involving entry manipulation /// and value retrieval. - pub trait Container + pub trait Collection { - /// The type of entries that can be added to the container. This type can differ from `Val` in containers like `HashMap`, + /// The type of entries that can be added to the collection. This type can differ from `Val` in collections like `HashMap`, /// where an entry might represent a key-value pair, and `Val` could represent just the value or the key. type Entry; - /// The type of values stored in the container. This might be distinct from `Entry` in complex containers. + /// The type of values stored in the collection. This might be distinct from `Entry` in complex collections. /// For example, in a `HashMap`, while `Entry` might be a ( key, value ) tuple, `Val` might only be the value part. type Val; - /// Converts an entry to its corresponding value within the container. This function is essential for abstracting - /// the container's internal representation from the values it manipulates. + /// Converts an entry to its corresponding value within the collection. This function is essential for abstracting + /// the collection's internal representation from the values it manipulates. fn entry_to_val( e : Self::Entry ) -> Self::Val; } - /// Provides functionality to add individual entries to a container. + /// Provides functionality to add individual entries to a collection. /// - /// This trait extends the basic `Container` trait by introducing a method to add entries to a container. - /// It is designed to handle the container's specific requirements and rules for adding entries, such as + /// This trait extends the basic `Collection` trait by introducing a method to add entries to a collection. + /// It is designed to handle the collection's specific requirements and rules for adding entries, such as /// managing duplicates, maintaining order, or handling capacity constraints. - pub trait ContainerAdd : Container + pub trait CollectionAdd : Collection { - /// Adds an entry to the container and returns a boolean indicating the success of the operation. + /// Adds an entry to the collection and returns a boolean indicating the success of the operation. /// - /// Implementations should ensure that the entry is added according to the rules of the container, + /// Implementations should ensure that the entry is added according to the rules of the collection, /// which might involve checking for duplicates, ordering, or capacity limits. /// /// # Parameters /// - /// * `e`: The entry to be added to the container, where the type `Entry` is defined by the `Container` trait. + /// * `e`: The entry to be added to the collection, where the type `Entry` is defined by the `Collection` trait. /// /// # Returns /// /// Returns `true` if the entry was successfully added, or `false` if not added due to reasons such as - /// the entry already existing in the container or the container reaching its capacity. + /// the entry already existing in the collection or the collection reaching its capacity. /// /// # Examples /// @@ -184,14 +184,14 @@ pub( crate ) mod private /// /// ```rust /// - /// use former::{ Container, ContainerAdd }; + /// use former::{ Collection, CollectionAdd }; /// - /// struct MyContainer + /// struct MyCollection /// { /// entries : Vec< i32 >, /// } /// - /// impl Container for MyContainer + /// impl Collection for MyCollection /// { /// type Entry = i32; /// type Val = i32; @@ -204,7 +204,7 @@ pub( crate ) mod private /// /// } /// - /// impl ContainerAdd for MyContainer + /// impl CollectionAdd for MyCollection /// { /// fn add( &mut self, e : Self::Entry ) -> bool /// { @@ -220,49 +220,49 @@ pub( crate ) mod private /// } /// } /// - /// let mut container = MyContainer { entries : vec![] }; - /// assert!( container.add( 10 ) ); // Returns true, entry added - /// assert!( !container.add( 10 ) ); // Returns false, entry already exists + /// let mut collection = MyCollection { entries : vec![] }; + /// assert!( collection.add( 10 ) ); // Returns true, entry added + /// assert!( !collection.add( 10 ) ); // Returns false, entry already exists /// ``` fn add( &mut self, e : Self::Entry ) -> bool; } - /// Defines the capability to replace all entries in a container with a new set of entries. + /// Defines the capability to replace all entries in a collection with a new set of entries. /// - /// This trait extends the `Container` trait by providing a method to replace the existing entries in - /// the container with a new set. This can be useful for resetting the container's contents or bulk-updating + /// This trait extends the `Collection` trait by providing a method to replace the existing entries in + /// the collection with a new set. This can be useful for resetting the collection's contents or bulk-updating /// them based on external criteria or operations. - pub trait ContainerAssign : Container + pub trait CollectionAssign : Collection where Self : IntoIterator< Item = Self::Entry >, { - /// Replaces all entries in the container with the provided entries and returns the count of new entries added. + /// Replaces all entries in the collection with the provided entries and returns the count of new entries added. /// - /// This method clears the existing entries and populates the container with new ones provided by an iterator. - /// It is ideal for scenarios where the container needs to be refreshed or updated with a new batch of entries. + /// This method clears the existing entries and populates the collection with new ones provided by an iterator. + /// It is ideal for scenarios where the collection needs to be refreshed or updated with a new batch of entries. /// /// # Parameters /// - /// * `entries` : An iterator over the entries to be added to the container. The entries must conform to - /// the `Entry` type defined by the `Container` trait. + /// * `entries` : An iterator over the entries to be added to the collection. The entries must conform to + /// the `Entry` type defined by the `Collection` trait. /// /// # Returns /// - /// Returns the number of entries successfully added to the container. This count may differ from the total - /// number of entries in the iterator if the container imposes restrictions such as capacity limits or duplicate + /// Returns the number of entries successfully added to the collection. This count may differ from the total + /// number of entries in the iterator if the collection imposes restrictions such as capacity limits or duplicate /// handling. /// /// # Examples /// /// ```rust - /// use former::{ Container, ContainerAssign }; + /// use former::{ Collection, CollectionAssign }; /// - /// struct MyContainer + /// struct MyCollection /// { /// entries : Vec< i32 >, /// } /// - /// impl Container for MyContainer + /// impl Collection for MyCollection /// { /// type Entry = i32; /// type Val = i32; @@ -275,7 +275,7 @@ pub( crate ) mod private /// /// } /// - /// impl IntoIterator for MyContainer + /// impl IntoIterator for MyCollection /// { /// type Item = i32; /// type IntoIter = std::vec::IntoIter< i32 >; @@ -288,7 +288,7 @@ pub( crate ) mod private /// } /// } /// - /// impl ContainerAssign for MyContainer + /// impl CollectionAssign for MyCollection /// { /// fn assign< Entries >( &mut self, entries : Entries ) -> usize /// where @@ -300,9 +300,9 @@ pub( crate ) mod private /// } /// } /// - /// let mut container = MyContainer { entries : vec![ 1, 2, 3 ] }; + /// let mut collection = MyCollection { entries : vec![ 1, 2, 3 ] }; /// let new_elements = vec![ 4, 5, 6 ]; - /// assert_eq!( container.assign( new_elements ), 3 ); // Container now contains [ 4, 5, 6 ] + /// assert_eq!( collection.assign( new_elements ), 3 ); // Collection now contains [ 4, 5, 6 ] /// ``` fn assign< Entries >( &mut self, entries : Entries ) -> usize where @@ -311,12 +311,12 @@ pub( crate ) mod private // = - /// A builder structure for constructing containers with a fluent and flexible interface. + /// A builder structure for constructing collections with a fluent and flexible interface. #[ derive( Default ) ] - pub struct ContainerFormer< E, Definition > + pub struct CollectionFormer< E, Definition > where Definition : FormerDefinition, - Definition::Storage : ContainerAdd< Entry = E >, + Definition::Storage : CollectionAdd< Entry = E >, { storage : Definition::Storage, context : core::option::Option< Definition::Context >, @@ -324,15 +324,15 @@ pub( crate ) mod private } use core::fmt; - impl< E, Definition > fmt::Debug for ContainerFormer< E, Definition > + impl< E, Definition > fmt::Debug for CollectionFormer< E, Definition > where Definition : FormerDefinition, - Definition::Storage : ContainerAdd< Entry = E >, + Definition::Storage : CollectionAdd< Entry = E >, { fn fmt( &self, f : &mut fmt::Formatter< '_ > ) -> fmt::Result { f - .debug_struct( "ContainerFormer" ) + .debug_struct( "CollectionFormer" ) .field( "storage", &"Storage Present" ) .field( "context", &self.context.as_ref().map( |_| "Context Present" ) ) .field( "on_end", &self.on_end.as_ref().map( |_| "End Present" ) ) @@ -340,13 +340,13 @@ pub( crate ) mod private } } - impl< E, Definition > ContainerFormer< E, Definition > + impl< E, Definition > CollectionFormer< E, Definition > where Definition : FormerDefinition, - Definition::Storage : ContainerAdd< Entry = E >, + Definition::Storage : CollectionAdd< Entry = E >, { - /// Begins the construction process of a container with optional initial storage and context, - /// setting up an `on_end` completion handler to finalize the container's construction. + /// Begins the construction process of a collection with optional initial storage and context, + /// setting up an `on_end` completion handler to finalize the collection's construction. #[ inline( always ) ] pub fn begin ( @@ -419,14 +419,14 @@ pub( crate ) mod private } } - impl< E, Storage, Formed, Definition > ContainerFormer< E, Definition > + impl< E, Storage, Formed, Definition > CollectionFormer< E, Definition > where Definition : FormerDefinition< Context = (), Storage = Storage, Formed = Formed >, - Definition::Storage : ContainerAdd< Entry = E >, + Definition::Storage : CollectionAdd< Entry = E >, { - /// Constructs a new `ContainerFormer` instance, starting with an empty storage. + /// Constructs a new `CollectionFormer` instance, starting with an empty storage. /// This method serves as the entry point for the builder pattern, facilitating the - /// creation of a new container. + /// creation of a new collection. #[ inline( always ) ] pub fn new( end : Definition::End ) -> Self { @@ -454,10 +454,10 @@ pub( crate ) mod private } } - impl< E, Definition > ContainerFormer< E, Definition > + impl< E, Definition > CollectionFormer< E, Definition > where Definition : FormerDefinition, - Definition::Storage : ContainerAdd< Entry = E >, + Definition::Storage : CollectionAdd< Entry = E >, { /// Appends an entry to the end of the storage, expanding the internal collection. @@ -465,7 +465,7 @@ pub( crate ) mod private pub fn add< IntoElement >( mut self, entry : IntoElement ) -> Self where IntoElement : core::convert::Into< E >, { - ContainerAdd::add( &mut self.storage, entry.into() ); + CollectionAdd::add( &mut self.storage, entry.into() ); self } @@ -474,10 +474,10 @@ pub( crate ) mod private // impl< E, Definition > FormerBegin< Definition > - for ContainerFormer< E, Definition > + for CollectionFormer< E, Definition > where Definition : FormerDefinition, - Definition::Storage : ContainerAdd< Entry = E >, + Definition::Storage : CollectionAdd< Entry = E >, { #[ inline( always ) ] @@ -537,13 +537,13 @@ pub mod exposed { EntryToVal, - ContainerValToEntry, + CollectionValToEntry, ValToEntry, - Container, - ContainerAdd, - ContainerAssign, - ContainerFormer, + Collection, + CollectionAdd, + CollectionAssign, + CollectionFormer, }; diff --git a/module/core/former/src/container/hash_map.rs b/module/core/former/src/collection/hash_map.rs similarity index 91% rename from module/core/former/src/container/hash_map.rs rename to module/core/former/src/collection/hash_map.rs index 6054850903..ebef51a479 100644 --- a/module/core/former/src/container/hash_map.rs +++ b/module/core/former/src/collection/hash_map.rs @@ -1,6 +1,6 @@ -//! This module provides a comprehensive approach to applying the builder pattern to `HashMap` containers. +//! This module provides a comprehensive approach to applying the builder pattern to `HashMap` collections. //! -//! By leveraging traits such as `Container`, `ContainerAdd`, `ContainerAssign`, and `ContainerValToEntry`, +//! By leveraging traits such as `Collection`, `CollectionAdd`, `CollectionAssign`, and `CollectionValToEntry`, //! this module abstracts the operations on hashmap-like data structures, making them more flexible and easier to integrate as //! as subformer, enabling fluid and intuitive manipulation of hashmaps via builder patterns. //! @@ -8,7 +8,7 @@ use crate::*; use collection_tools::HashMap; -impl< K, V > Container for collection_tools::HashMap< K, V > +impl< K, V > Collection for collection_tools::HashMap< K, V > where K : core::cmp::Eq + core::hash::Hash, { @@ -23,7 +23,7 @@ where } -impl< K, V > ContainerAdd for collection_tools::HashMap< K, V > +impl< K, V > CollectionAdd for collection_tools::HashMap< K, V > where K : core::cmp::Eq + core::hash::Hash, { @@ -36,7 +36,7 @@ where } -impl< K, V > ContainerAssign for collection_tools::HashMap< K, V > +impl< K, V > CollectionAssign for collection_tools::HashMap< K, V > where K : core::cmp::Eq + core::hash::Hash, { @@ -74,9 +74,9 @@ where // = definition -/// Represents the formation definition for a hash map-like container within the former framework. +/// Represents the formation definition for a hash map-like collection within the former framework. /// -/// This structure defines the essential elements required to form a hash map-like container, detailing +/// This structure defines the essential elements required to form a hash map-like collection, detailing /// the key and value types, the contextual environment during formation, the final formed type, and the /// behavior at the end of the formation process. It facilitates customization and extension of hash map /// formation within any system that implements complex data management operations. @@ -202,9 +202,9 @@ where // = subformer -/// Provides a streamlined builder interface for constructing hash map-like containers. +/// Provides a streamlined builder interface for constructing hash map-like collections. /// -/// `HashMapFormer` is a type alias that configures the `ContainerFormer` specifically for hash maps, +/// `HashMapFormer` is a type alias that configures the `CollectionFormer` specifically for hash maps, /// facilitating a more intuitive and flexible way to build and manipulate hash maps within custom data structures. /// This type alias simplifies the usage of hash maps in builder patterns by encapsulating complex generic parameters /// and leveraging the `HashMapDefinition` to handle the construction logic. It supports fluent chaining of key-value @@ -214,7 +214,7 @@ where /// a builder pattern both efficient and expressive. pub type HashMapFormer< K, E, Context, Formed, End > = -ContainerFormer::< ( K, E ), HashMapDefinition< K, E, Context, Formed, End > >; +CollectionFormer::< ( K, E ), HashMapDefinition< K, E, Context, Formed, End > >; // = extension diff --git a/module/core/former/src/container/hash_set.rs b/module/core/former/src/collection/hash_set.rs similarity index 85% rename from module/core/former/src/container/hash_set.rs rename to module/core/former/src/collection/hash_set.rs index 6e96684ee1..ab77440ec8 100644 --- a/module/core/former/src/container/hash_set.rs +++ b/module/core/former/src/collection/hash_set.rs @@ -1,9 +1,9 @@ -//! This module provides a builder pattern implementation (`HashSetFormer`) for `HashSet`-like containers. It is designed to extend the builder pattern, allowing for fluent and dynamic construction of sets within custom data structures. +//! This module provides a builder pattern implementation (`HashSetFormer`) for `HashSet`-like collections. It is designed to extend the builder pattern, allowing for fluent and dynamic construction of sets within custom data structures. use crate::*; use collection_tools::HashSet; -impl< K > Container for collection_tools::HashSet< K > +impl< K > Collection for collection_tools::HashSet< K > where K : core::cmp::Eq + core::hash::Hash, { @@ -18,7 +18,7 @@ where } -impl< K > ContainerAdd for collection_tools::HashSet< K > +impl< K > CollectionAdd for collection_tools::HashSet< K > where K : core::cmp::Eq + core::hash::Hash, { @@ -33,7 +33,7 @@ where } -impl< K > ContainerAssign for collection_tools::HashSet< K > +impl< K > CollectionAssign for collection_tools::HashSet< K > where K : core::cmp::Eq + core::hash::Hash, { @@ -49,7 +49,7 @@ where } } -impl< K > ContainerValToEntry< K > for HashSet< K > +impl< K > CollectionValToEntry< K > for HashSet< K > where K : core::cmp::Eq + core::hash::Hash, { @@ -61,7 +61,7 @@ where } } -// /// A trait for containers behaving like a `HashSet`, allowing insertion operations. +// /// A trait for collections behaving like a `HashSet`, allowing insertion operations. // /// // /// Implementing this trait enables the associated formed to be used with `HashSetFormer`, // /// facilitating a builder pattern that is both intuitive and concise. @@ -114,12 +114,12 @@ where // = definition -/// Represents the formation definition for a hash set-like container within the former framework. +/// Represents the formation definition for a hash set-like collection within the former framework. /// -/// This structure defines the essential elements required to form a hash set-like container, detailing +/// This structure defines the essential elements required to form a hash set-like collection, detailing /// the type of elements, the contextual environment during formation, the final formed type, and the /// behavior at the end of the formation process. It is designed to support the construction and configuration -/// of hash set containers with dynamic characteristics and behaviors. +/// of hash set collections with dynamic characteristics and behaviors. /// /// # Type Parameters /// - `K`: The type of elements in the hash set. @@ -233,15 +233,15 @@ where // = subformer -/// Provides a concise alias for `ContainerFormer` configured specifically for `HashSet`-like containers. +/// Provides a concise alias for `CollectionFormer` configured specifically for `HashSet`-like collections. /// -/// `HashSetFormer` simplifies the creation of `HashSet` containers within builder patterns by leveraging -/// the `ContainerFormer` with predefined settings. This approach minimizes boilerplate code and enhances -/// readability, making it ideal for fluent and expressive construction of set containers within custom data structures. +/// `HashSetFormer` simplifies the creation of `HashSet` collections within builder patterns by leveraging +/// the `CollectionFormer` with predefined settings. This approach minimizes boilerplate code and enhances +/// readability, making it ideal for fluent and expressive construction of set collections within custom data structures. /// pub type HashSetFormer< K, Context, Formed, End > = -ContainerFormer::< K, HashSetDefinition< K, Context, Formed, End > >; +CollectionFormer::< K, HashSetDefinition< K, Context, Formed, End > >; // = extension diff --git a/module/core/former/src/container/vector.rs b/module/core/former/src/collection/vector.rs similarity index 89% rename from module/core/former/src/container/vector.rs rename to module/core/former/src/collection/vector.rs index 33c344d1ab..d3b707c03b 100644 --- a/module/core/former/src/container/vector.rs +++ b/module/core/former/src/collection/vector.rs @@ -1,6 +1,6 @@ -//! This module provides a comprehensive approach to applying the builder pattern to `Vec` containers. +//! This module provides a comprehensive approach to applying the builder pattern to `Vec` collections. //! -//! By leveraging traits such as `Container`, `ContainerAdd`, `ContainerAssign`, and `ContainerValToEntry`, +//! By leveraging traits such as `Collection`, `CollectionAdd`, `CollectionAssign`, and `CollectionValToEntry`, //! this module abstracts the operations on vector-like data structures, making them more flexible and easier to integrate as //! as subformer, enabling fluid and intuitive manipulation of vectors via builder patterns. //! @@ -9,7 +9,7 @@ use crate::*; #[ allow( unused ) ] use collection_tools::Vec; -impl< E > Container for collection_tools::Vec< E > +impl< E > Collection for collection_tools::Vec< E > { type Entry = E; type Val = E; @@ -22,7 +22,7 @@ impl< E > Container for collection_tools::Vec< E > } -impl< E > ContainerAdd for collection_tools::Vec< E > +impl< E > CollectionAdd for collection_tools::Vec< E > { #[ inline( always ) ] @@ -34,7 +34,7 @@ impl< E > ContainerAdd for collection_tools::Vec< E > } -impl< E > ContainerAssign for collection_tools::Vec< E > +impl< E > CollectionAssign for collection_tools::Vec< E > { #[ inline( always ) ] fn assign< Elements >( &mut self, elements : Elements ) -> usize @@ -48,7 +48,7 @@ impl< E > ContainerAssign for collection_tools::Vec< E > } -impl< E > ContainerValToEntry< E > for collection_tools::Vec< E > +impl< E > CollectionValToEntry< E > for collection_tools::Vec< E > where { type Entry = E; @@ -78,9 +78,9 @@ for Vec< E > // = definition -/// Represents the formation definition for a vector-like container within the former framework. +/// Represents the formation definition for a vector-like collection within the former framework. /// -/// This structure defines the necessary parameters and relationships needed to form a vector-like container, +/// This structure defines the necessary parameters and relationships needed to form a vector-like collection, /// including its storage, context, the result of the formation process, and the behavior at the end of the formation. /// /// # Type Parameters @@ -189,9 +189,9 @@ for Vec< E > // = subformer -/// Provides a streamlined builder interface for constructing vector-like containers. +/// Provides a streamlined builder interface for constructing vector-like collections. /// -/// `VectorFormer` is a type alias that configures the `ContainerFormer` for use specifically with vectors. +/// `VectorFormer` is a type alias that configures the `CollectionFormer` for use specifically with vectors. /// It integrates the `VectorDefinition` to facilitate the fluent and dynamic construction of vectors, leveraging /// predefined settings to reduce boilerplate code. This approach enhances readability and simplifies the use of /// vectors in custom data structures where builder patterns are desired. @@ -202,7 +202,7 @@ for Vec< E > /// pub type VectorFormer< E, Context, Formed, End > = -ContainerFormer::< E, VectorDefinition< E, Context, Formed, End > >; +CollectionFormer::< E, VectorDefinition< E, Context, Formed, End > >; // = extension diff --git a/module/core/former/src/forming.rs b/module/core/former/src/forming.rs index 892f4ad526..d95bea8666 100644 --- a/module/core/former/src/forming.rs +++ b/module/core/former/src/forming.rs @@ -57,7 +57,7 @@ where /// Implementors can define how to transform or pass through the context during the forming process's completion. /// /// # Parameters -/// - `Storage`: The type of the container being processed. +/// - `Storage`: The type of the collection being processed. /// - `Context`: The type of the context that might be altered or returned upon completion. pub trait FormingEnd< Definition : crate::FormerDefinitionTypes > @@ -65,7 +65,7 @@ pub trait FormingEnd< Definition : crate::FormerDefinitionTypes > /// Called at the end of the subforming process to return the modified or original context. /// /// # Parameters - /// - `container`: The container being processed. + /// - `collection`: The collection being processed. /// - `context`: Optional context to be transformed or returned. /// /// # Returns @@ -85,9 +85,9 @@ where } } -/// A `FormingEnd` implementation that directly returns the formed container as the final product of the forming process. +/// A `FormingEnd` implementation that directly returns the formed collection as the final product of the forming process. /// -/// This struct is particularly useful when the end result of the forming process is simply the formed container itself, +/// This struct is particularly useful when the end result of the forming process is simply the formed collection itself, /// without needing to integrate or process additional contextual information. It's ideal for scenarios where the final /// entity is directly derived from the storage state without further transformations or context-dependent adjustments. #[ derive( Debug, Default ) ] @@ -193,7 +193,7 @@ impl< Definition : crate::FormerDefinitionTypes > FormingEndClosure< Definition /// /// # Parameters /// - /// * `closure` - A closure that matches the expected signature for transforming a container + /// * `closure` - A closure that matches the expected signature for transforming a collection /// and context into a new context. This closure is stored and called by the /// `call` method of the `FormingEnd` trait implementation. /// diff --git a/module/core/former/src/lib.rs b/module/core/former/src/lib.rs index 9653b8152e..85b73f8e13 100644 --- a/module/core/former/src/lib.rs +++ b/module/core/former/src/lib.rs @@ -21,11 +21,11 @@ mod forming; #[ cfg( feature = "derive_former" ) ] mod storage; -/// Interface for containers. +/// Interface for collections. #[ cfg( feature = "enabled" ) ] #[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] #[ cfg( feature = "derive_former" ) ] -mod container; +mod collection; /// Component-based forming. #[ cfg( feature = "enabled" ) ] @@ -95,7 +95,7 @@ pub mod exposed #[ cfg( feature = "enabled" ) ] #[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] #[ cfg( feature = "derive_former" ) ] - pub use super::container::*; + pub use super::collection::*; } diff --git a/module/core/former/tests/inc/former_tests/a_primitives_manual.rs b/module/core/former/tests/inc/former_tests/a_primitives_manual.rs index 90e1290d6b..baafc6e1ae 100644 --- a/module/core/former/tests/inc/former_tests/a_primitives_manual.rs +++ b/module/core/former/tests/inc/former_tests/a_primitives_manual.rs @@ -203,7 +203,6 @@ where return result; } - // xxx : update description #[ inline( always ) ] pub fn new( on_end : Definition::End ) -> Self { diff --git a/module/core/former/tests/inc/former_tests/attribute_default_container.rs b/module/core/former/tests/inc/former_tests/attribute_default_collection.rs similarity index 100% rename from module/core/former/tests/inc/former_tests/attribute_default_container.rs rename to module/core/former/tests/inc/former_tests/attribute_default_collection.rs diff --git a/module/core/former/tests/inc/former_tests/container_former_common.rs b/module/core/former/tests/inc/former_tests/collection_former_common.rs similarity index 85% rename from module/core/former/tests/inc/former_tests/container_former_common.rs rename to module/core/former/tests/inc/former_tests/collection_former_common.rs index 3bc9c84dfc..80ed29689e 100644 --- a/module/core/former/tests/inc/former_tests/container_former_common.rs +++ b/module/core/former/tests/inc/former_tests/collection_former_common.rs @@ -132,14 +132,14 @@ fn custom_definition() // - let got = former::ContainerFormer::< String, Return13 >::begin( None, None, Return13 ) + let got = former::CollectionFormer::< String, Return13 >::begin( None, None, Return13 ) .add( "a" ) .add( "b" ) .form(); let exp = 13; a_id!( got, exp ); - let got = former::ContainerFormer::< String, Return13 >::new( Return13 ) + let got = former::CollectionFormer::< String, Return13 >::new( Return13 ) .add( "a" ) .add( "b" ) .form(); @@ -205,14 +205,14 @@ fn custom_definition_parametrized() // - let got = the_module::ContainerFormer::< String, Return13< String > >::begin_coercing( None, None, Return13::new() ) + let got = the_module::CollectionFormer::< String, Return13< String > >::begin_coercing( None, None, Return13::new() ) .add( "a" ) .add( "b" ) .form(); let exp = 13; a_id!( got, exp ); - let got = the_module::ContainerFormer::< String, Return13< String > >::new_coercing( Return13::new() ) + let got = the_module::CollectionFormer::< String, Return13< String > >::new_coercing( Return13::new() ) .add( "a" ) .add( "b" ) .form(); @@ -221,16 +221,16 @@ fn custom_definition_parametrized() // - type MyContainer< E > = the_module::ContainerFormer::< E, Return13< E > >; + type MyCollection< E > = the_module::CollectionFormer::< E, Return13< E > >; - let got = MyContainer::< String >::begin_coercing( None, None, Return13::new() ) + let got = MyCollection::< String >::begin_coercing( None, None, Return13::new() ) .add( "a" ) .add( "b" ) .form(); let exp = 13; a_id!( got, exp ); - let got = MyContainer::< String >::new_coercing( Return13::new() ) + let got = MyCollection::< String >::new_coercing( Return13::new() ) .add( "a" ) .add( "b" ) .form(); @@ -273,21 +273,21 @@ fn custom_definition_custom_end() } let end_wrapper : the_module::FormingEndClosure< Return13 > = the_module::FormingEndClosure::new( return_13 ); - let got = the_module::ContainerFormer::< String, Return13 >::new( end_wrapper ) + let got = the_module::CollectionFormer::< String, Return13 >::new( end_wrapper ) .add( "a" ) .add( "b" ) .form(); let exp = 13; a_id!( got, exp ); - let got = the_module::ContainerFormer::< String, Return13 >::new( return_13.into() ) + let got = the_module::CollectionFormer::< String, Return13 >::new( return_13.into() ) .add( "a" ) .add( "b" ) .form(); let exp = 13; a_id!( got, exp ); - let got = the_module::ContainerFormer::< String, Return13 >::new_coercing( return_13 ) + let got = the_module::CollectionFormer::< String, Return13 >::new_coercing( return_13 ) .add( "a" ) .add( "b" ) .form(); diff --git a/module/core/former/tests/inc/former_tests/container_former_hashmap.rs b/module/core/former/tests/inc/former_tests/collection_former_hashmap.rs similarity index 98% rename from module/core/former/tests/inc/former_tests/container_former_hashmap.rs rename to module/core/former/tests/inc/former_tests/collection_former_hashmap.rs index 1b34ebbb3b..ac0a6abedf 100644 --- a/module/core/former/tests/inc/former_tests/container_former_hashmap.rs +++ b/module/core/former/tests/inc/former_tests/collection_former_hashmap.rs @@ -11,10 +11,10 @@ use collection_tools::HashMap; fn add() { - // expliccit with ContainerFormer + // expliccit with CollectionFormer let got : HashMap< String, String > = the_module - ::ContainerFormer + ::CollectionFormer ::< ( String, String ), former::HashMapDefinition< String, String, (), HashMap< String, String >, the_module::ReturnStorage > > ::new( former::ReturnStorage ) .add( ( "a".into(), "x".into() ) ) diff --git a/module/core/former/tests/inc/former_tests/container_former_hashset.rs b/module/core/former/tests/inc/former_tests/collection_former_hashset.rs similarity index 97% rename from module/core/former/tests/inc/former_tests/container_former_hashset.rs rename to module/core/former/tests/inc/former_tests/collection_former_hashset.rs index 83b8e7a994..c3fa89935a 100644 --- a/module/core/former/tests/inc/former_tests/container_former_hashset.rs +++ b/module/core/former/tests/inc/former_tests/collection_former_hashset.rs @@ -11,10 +11,10 @@ use collection_tools::HashSet; fn add() { - // expliccit with ContainerFormer + // expliccit with CollectionFormer let got : HashSet< String > = the_module - ::ContainerFormer + ::CollectionFormer ::< String, former::HashSetDefinition< String, (), HashSet< String >, the_module::ReturnStorage > > ::new( former::ReturnStorage ) .add( "a" ) diff --git a/module/core/former/tests/inc/former_tests/container_former_vec.rs b/module/core/former/tests/inc/former_tests/collection_former_vec.rs similarity index 96% rename from module/core/former/tests/inc/former_tests/container_former_vec.rs rename to module/core/former/tests/inc/former_tests/collection_former_vec.rs index ec76210448..b9eb91c6f8 100644 --- a/module/core/former/tests/inc/former_tests/container_former_vec.rs +++ b/module/core/former/tests/inc/former_tests/collection_former_vec.rs @@ -10,10 +10,10 @@ use collection_tools::Vec; fn add() { - // expliccit with ContainerFormer + // expliccit with CollectionFormer let got : Vec< String > = the_module - ::ContainerFormer + ::CollectionFormer ::< String, former::VectorDefinition< String, (), Vec< String >, the_module::ReturnStorage > > ::new( former::ReturnStorage ) .add( "a" ) @@ -105,7 +105,7 @@ fn replace() // -// qqq : make similar test for all containers +// qqq : make similar test for all collections #[ test ] fn entity_to() { diff --git a/module/core/former/tests/inc/former_tests/name_collisions.rs b/module/core/former/tests/inc/former_tests/name_collisions.rs index 843af61803..9d935c81b8 100644 --- a/module/core/former/tests/inc/former_tests/name_collisions.rs +++ b/module/core/former/tests/inc/former_tests/name_collisions.rs @@ -34,4 +34,4 @@ pub struct Struct1 // -include!( "./only_test/containers_without_subformer.rs" ); +include!( "./only_test/collections_without_subformer.rs" ); diff --git a/module/core/former/tests/inc/former_tests/only_test/containers_with_subformer.rs b/module/core/former/tests/inc/former_tests/only_test/collections_with_subformer.rs similarity index 96% rename from module/core/former/tests/inc/former_tests/only_test/containers_with_subformer.rs rename to module/core/former/tests/inc/former_tests/only_test/collections_with_subformer.rs index 042d36e538..0c57911f19 100644 --- a/module/core/former/tests/inc/former_tests/only_test/containers_with_subformer.rs +++ b/module/core/former/tests/inc/former_tests/only_test/collections_with_subformer.rs @@ -121,10 +121,10 @@ tests_impls! fn field_forming_end() { - // Container subformers are defined - let _got = Struct1FormerAssignVec1End::< Struct1FormerDefinition >::default(); - let _got = Struct1FormerAssignHashmap1End::< Struct1FormerDefinition >::default(); - let _got = Struct1FormerAssignHashset1End::< Struct1FormerDefinition >::default(); + // Collection subformers are defined + let _got = Struct1SubformCollectionVec1End::< Struct1FormerDefinition >::default(); + let _got = Struct1SubformCollectionHashmap1End::< Struct1FormerDefinition >::default(); + let _got = Struct1SubformCollectionHashset1End::< Struct1FormerDefinition >::default(); // AsSubformerEnd is defined fn _f1< End : Struct1AsSubformerEnd< Struct1Former > > diff --git a/module/core/former/tests/inc/former_tests/only_test/containers_without_subformer.rs b/module/core/former/tests/inc/former_tests/only_test/collections_without_subformer.rs similarity index 100% rename from module/core/former/tests/inc/former_tests/only_test/containers_without_subformer.rs rename to module/core/former/tests/inc/former_tests/only_test/collections_without_subformer.rs diff --git a/module/core/former/tests/inc/former_tests/only_test/subformer_scalar_children.rs b/module/core/former/tests/inc/former_tests/only_test/scalar_children.rs similarity index 100% rename from module/core/former/tests/inc/former_tests/only_test/subformer_scalar_children.rs rename to module/core/former/tests/inc/former_tests/only_test/scalar_children.rs diff --git a/module/core/former/tests/inc/former_tests/only_test/subformer_scalar_children3.rs b/module/core/former/tests/inc/former_tests/only_test/scalar_children3.rs similarity index 100% rename from module/core/former/tests/inc/former_tests/only_test/subformer_scalar_children3.rs rename to module/core/former/tests/inc/former_tests/only_test/scalar_children3.rs diff --git a/module/core/former/tests/inc/former_tests/only_test/subformer_basic.rs b/module/core/former/tests/inc/former_tests/only_test/subform_basic.rs similarity index 100% rename from module/core/former/tests/inc/former_tests/only_test/subformer_basic.rs rename to module/core/former/tests/inc/former_tests/only_test/subform_basic.rs diff --git a/module/core/former/tests/inc/former_tests/only_test/subformer_container.rs b/module/core/former/tests/inc/former_tests/only_test/subform_collection.rs similarity index 100% rename from module/core/former/tests/inc/former_tests/only_test/subformer_container.rs rename to module/core/former/tests/inc/former_tests/only_test/subform_collection.rs diff --git a/module/core/former/tests/inc/former_tests/only_test/subformer_container_children2.rs b/module/core/former/tests/inc/former_tests/only_test/subform_collection_children2.rs similarity index 95% rename from module/core/former/tests/inc/former_tests/only_test/subformer_container_children2.rs rename to module/core/former/tests/inc/former_tests/only_test/subform_collection_children2.rs index 46fae25331..4821ab23e8 100644 --- a/module/core/former/tests/inc/former_tests/only_test/subformer_container_children2.rs +++ b/module/core/former/tests/inc/former_tests/only_test/subform_collection_children2.rs @@ -1,6 +1,6 @@ #[ test ] -fn container() +fn collection() { let got = Parent::former() diff --git a/module/core/former/tests/inc/former_tests/only_test/subformer_subform_child.rs b/module/core/former/tests/inc/former_tests/only_test/subform_entry_child.rs similarity index 100% rename from module/core/former/tests/inc/former_tests/only_test/subformer_subform_child.rs rename to module/core/former/tests/inc/former_tests/only_test/subform_entry_child.rs diff --git a/module/core/former/tests/inc/former_tests/only_test/subformer_subform_children2.rs b/module/core/former/tests/inc/former_tests/only_test/subform_entry_children2.rs similarity index 100% rename from module/core/former/tests/inc/former_tests/only_test/subformer_subform_children2.rs rename to module/core/former/tests/inc/former_tests/only_test/subform_entry_children2.rs diff --git a/module/core/former/tests/inc/former_tests/only_test/subform_scalar.rs b/module/core/former/tests/inc/former_tests/only_test/subform_scalar.rs new file mode 100644 index 0000000000..90ba084724 --- /dev/null +++ b/module/core/former/tests/inc/former_tests/only_test/subform_scalar.rs @@ -0,0 +1,13 @@ + +#[ test ] +fn subforme_scalar() +{ + + let got = Parent::former() + .child().name( "a" ).data( true ).end() + .form(); + + let exp = Parent { child : Child { name : "a".to_string(), data : true } }; + a_id!( got, exp ); + +} diff --git a/module/core/former/tests/inc/former_tests/string_slice.rs b/module/core/former/tests/inc/former_tests/parametrized_slice.rs similarity index 100% rename from module/core/former/tests/inc/former_tests/string_slice.rs rename to module/core/former/tests/inc/former_tests/parametrized_slice.rs diff --git a/module/core/former/tests/inc/former_tests/string_slice_manual.rs b/module/core/former/tests/inc/former_tests/parametrized_slice_manual.rs similarity index 100% rename from module/core/former/tests/inc/former_tests/string_slice_manual.rs rename to module/core/former/tests/inc/former_tests/parametrized_slice_manual.rs diff --git a/module/core/former/tests/inc/former_tests/parametrized_struct_imm.rs b/module/core/former/tests/inc/former_tests/parametrized_struct_imm.rs index d216575504..8ffd7ad762 100644 --- a/module/core/former/tests/inc/former_tests/parametrized_struct_imm.rs +++ b/module/core/former/tests/inc/former_tests/parametrized_struct_imm.rs @@ -28,7 +28,7 @@ impl< Name > Property< Name > pub struct Child< K : core::hash::Hash + std::cmp::Eq > { pub name : String, - #[ container( definition = former::HashMapDefinition ) ] + #[ subform_collection( definition = former::HashMapDefinition ) ] pub properties : collection_tools::HashMap< K, Property< K > >, } diff --git a/module/core/former/tests/inc/former_tests/parametrized_struct_manual.rs b/module/core/former/tests/inc/former_tests/parametrized_struct_manual.rs index 95e081b39e..efab5306c5 100644 --- a/module/core/former/tests/inc/former_tests/parametrized_struct_manual.rs +++ b/module/core/former/tests/inc/former_tests/parametrized_struct_manual.rs @@ -30,7 +30,7 @@ where K : core::hash::Hash + std::cmp::Eq, { pub name : String, - // #[ container( definition = former::HashMapDefinition ) ] + // #[ subform_collection( definition = former::HashMapDefinition ) ] pub properties : collection_tools::HashMap< K, Property< K > >, } @@ -318,9 +318,9 @@ where } #[ inline( always ) ] - pub fn properties( self ) -> former::ContainerFormer::< ( K, Property< K >, ), former::HashMapDefinition< K, Property< K >, Self, Self, ChildFormerPropertiesEnd > > + pub fn properties( self ) -> former::CollectionFormer::< ( K, Property< K >, ), former::HashMapDefinition< K, Property< K >, Self, Self, ChildFormerPropertiesEnd > > { - self.properties_set::< former::ContainerFormer::< ( K, Property< K >, ), former::HashMapDefinition< K, Property< K >, Self, Self, ChildFormerPropertiesEnd > >>() + self.properties_set::< former::CollectionFormer::< ( K, Property< K >, ), former::HashMapDefinition< K, Property< K >, Self, Self, ChildFormerPropertiesEnd > >>() } } @@ -356,7 +356,7 @@ where let mut super_former = super_former.unwrap(); if let Some( ref mut field ) = super_former.storage.properties { - former::ContainerAssign::assign( field, storage ); + former::CollectionAssign::assign( field, storage ); } else { diff --git a/module/core/former/tests/inc/former_tests/parametrized_struct_where.rs b/module/core/former/tests/inc/former_tests/parametrized_struct_where.rs index 063e58be1c..b45429c63c 100644 --- a/module/core/former/tests/inc/former_tests/parametrized_struct_where.rs +++ b/module/core/former/tests/inc/former_tests/parametrized_struct_where.rs @@ -30,7 +30,7 @@ where K : core::hash::Hash + std::cmp::Eq, { pub name : String, - #[ container( definition = former::HashMapDefinition ) ] + #[ subform_collection( definition = former::HashMapDefinition ) ] pub properties : collection_tools::HashMap< K, Property< K > >, } diff --git a/module/core/former/tests/inc/former_tests/subformer_subform_and_container.rs b/module/core/former/tests/inc/former_tests/subform_all.rs similarity index 79% rename from module/core/former/tests/inc/former_tests/subformer_subform_and_container.rs rename to module/core/former/tests/inc/former_tests/subform_all.rs index 6a3546113e..6a4cd78a03 100644 --- a/module/core/former/tests/inc/former_tests/subformer_subform_and_container.rs +++ b/module/core/former/tests/inc/former_tests/subform_all.rs @@ -16,9 +16,9 @@ pub struct Child // #[ derive( Debug, Default, PartialEq ) ] pub struct Parent { - #[ subform( name = _child ) ] - #[ container( name = children2 ) ] #[ scalar( name = children3 ) ] + #[ subform_collection( name = children2 ) ] + #[ subform_entry( name = _child ) ] children : Vec< Child >, } @@ -31,7 +31,7 @@ where pub fn child( self, name : &str ) -> ChildAsSubformer< Self, impl ChildAsSubformerEnd< Self > > { - self._children_add + self._children_subform_entry ::< ChildFormer< _ >, _, >() .name( name ) } @@ -51,6 +51,6 @@ where // == end of generated -include!( "./only_test/subformer_subform_child.rs" ); -include!( "./only_test/subformer_container_children2.rs" ); -include!( "./only_test/subformer_scalar_children3.rs" ); +include!( "./only_test/subform_entry_child.rs" ); +include!( "./only_test/subform_collection_children2.rs" ); +include!( "./only_test/scalar_children3.rs" ); diff --git a/module/core/former/tests/inc/former_tests/subformer_subform_and_container_parametrized.rs b/module/core/former/tests/inc/former_tests/subform_all_parametrized.rs similarity index 89% rename from module/core/former/tests/inc/former_tests/subformer_subform_and_container_parametrized.rs rename to module/core/former/tests/inc/former_tests/subform_all_parametrized.rs index 43347fc9ce..3f754f164c 100644 --- a/module/core/former/tests/inc/former_tests/subformer_subform_and_container_parametrized.rs +++ b/module/core/former/tests/inc/former_tests/subform_all_parametrized.rs @@ -20,9 +20,9 @@ where // #[ derive( Debug, Default, PartialEq ) ] pub struct Parent< 'child > { - #[ subform( name = _child ) ] - #[ container( name = children2 ) ] #[ scalar( name = children3 ) ] + #[ subform_collection( name = children2 ) ] + #[ subform_entry( name = _child ) ] children : Vec< Child< 'child, str > >, } @@ -35,7 +35,7 @@ where pub fn child( self, name : &str ) -> ChildAsSubformer< 'child, str, Self, impl ChildAsSubformerEnd< 'child, str, Self > > { - self._children_add + self._children_subform_entry ::< ChildFormer< '_, _, _ >, _, >() .name( name ) } @@ -85,7 +85,7 @@ fn subform_child_generated() } #[ test ] -fn container() +fn collection() { let got = Parent::former() @@ -129,6 +129,6 @@ fn scalar() } -// include!( "./only_test/subformer_subform_child.rs" ); -// include!( "./only_test/subformer_container_children2.rs" ); -// include!( "./only_test/subformer_scalar_children3.rs" ); +// include!( "./only_test/subform_entry_child.rs" ); +// include!( "./only_test/subform_collection_children2.rs" ); +// include!( "./only_test/subform_scalar_children3.rs" ); diff --git a/module/core/former/tests/inc/former_tests/subformer_subform_and_container_private.rs b/module/core/former/tests/inc/former_tests/subform_all_private.rs similarity index 79% rename from module/core/former/tests/inc/former_tests/subformer_subform_and_container_private.rs rename to module/core/former/tests/inc/former_tests/subform_all_private.rs index 1c915adce1..df7f1e4738 100644 --- a/module/core/former/tests/inc/former_tests/subformer_subform_and_container_private.rs +++ b/module/core/former/tests/inc/former_tests/subform_all_private.rs @@ -16,9 +16,9 @@ struct Child // #[ derive( Debug, Default, PartialEq ) ] struct Parent { - #[ subform( name = _child ) ] - #[ container( name = children2 ) ] #[ scalar( name = children3 ) ] + #[ subform_collection( name = children2 ) ] + #[ subform_entry( name = _child ) ] children : Vec< Child >, } @@ -31,7 +31,7 @@ where fn child( self, name : &str ) -> ChildAsSubformer< Self, impl ChildAsSubformerEnd< Self > > { - self._children_add + self._children_subform_entry ::< ChildFormer< _ >, _, >() .name( name ) } @@ -51,6 +51,6 @@ where // == end of generated -include!( "./only_test/subformer_subform_child.rs" ); -include!( "./only_test/subformer_container_children2.rs" ); -include!( "./only_test/subformer_scalar_children3.rs" ); +include!( "./only_test/subform_entry_child.rs" ); +include!( "./only_test/subform_collection_children2.rs" ); +include!( "./only_test/scalar_children3.rs" ); diff --git a/module/core/former/tests/inc/former_tests/subformer_container.rs b/module/core/former/tests/inc/former_tests/subform_collection.rs similarity index 81% rename from module/core/former/tests/inc/former_tests/subformer_container.rs rename to module/core/former/tests/inc/former_tests/subform_collection.rs index c168f83e8b..782cc7f213 100644 --- a/module/core/former/tests/inc/former_tests/subformer_container.rs +++ b/module/core/former/tests/inc/former_tests/subform_collection.rs @@ -16,7 +16,7 @@ pub struct Child // #[ derive( Debug, Default, PartialEq ) ] pub struct Parent { - #[ container( definition = former::VectorDefinition ) ] + #[ subform_collection( definition = former::VectorDefinition ) ] children : Vec< Child >, } @@ -24,4 +24,4 @@ pub struct Parent // == end of generated -include!( "./only_test/subformer_container.rs" ); +include!( "./only_test/subform_collection.rs" ); diff --git a/module/core/former/tests/inc/former_tests/a_containers.rs b/module/core/former/tests/inc/former_tests/subform_collection_basic.rs similarity index 66% rename from module/core/former/tests/inc/former_tests/a_containers.rs rename to module/core/former/tests/inc/former_tests/subform_collection_basic.rs index c2466841bf..1fcf5792cd 100644 --- a/module/core/former/tests/inc/former_tests/a_containers.rs +++ b/module/core/former/tests/inc/former_tests/subform_collection_basic.rs @@ -11,11 +11,11 @@ use super::*; // #[ derive( Default, Debug, PartialEq ) ] pub struct Struct1 { - #[ container( definition = former::VectorDefinition ) ] + #[ subform_collection( definition = former::VectorDefinition ) ] vec_1 : Vec< String >, - #[ container( definition = former::HashMapDefinition ) ] + #[ subform_collection( definition = former::HashMapDefinition ) ] hashmap_1 : std::collections::HashMap< String, String >, - #[ container( definition = former::HashSetDefinition ) ] + #[ subform_collection( definition = former::HashSetDefinition ) ] hashset_1 : std::collections::HashSet< String >, } @@ -23,4 +23,4 @@ pub struct Struct1 // == generated end -include!( "./only_test/containers_with_subformer.rs" ); +include!( "./only_test/collections_with_subformer.rs" ); diff --git a/module/core/former/tests/inc/former_tests/a_containers_manual.rs b/module/core/former/tests/inc/former_tests/subform_collection_basic_manual.rs similarity index 77% rename from module/core/former/tests/inc/former_tests/a_containers_manual.rs rename to module/core/former/tests/inc/former_tests/subform_collection_basic_manual.rs index eed2cbfa9a..314bace671 100644 --- a/module/core/former/tests/inc/former_tests/a_containers_manual.rs +++ b/module/core/former/tests/inc/former_tests/subform_collection_basic_manual.rs @@ -16,8 +16,6 @@ impl< > Struct1< > where { - - #[ inline( always ) ] pub fn former() -> Struct1Former< Struct1FormerDefinition<(), Struct1<>, former::ReturnPreformed> @@ -343,46 +341,46 @@ where where Former2 : former::FormerBegin < - former::VectorDefinition< String, Self, Self, Struct1FormerAssignVec1End< Definition > >, + former::VectorDefinition< String, Self, Self, Struct1SubformCollectionVec1End< Definition > >, >, - former::VectorDefinition< String, Self, Self, Struct1FormerAssignVec1End< Definition > > : former::FormerDefinition + former::VectorDefinition< String, Self, Self, Struct1SubformCollectionVec1End< Definition > > : former::FormerDefinition < - // Storage : former::ContainerAdd< Entry = < collection_tools::Vec< String > as former::Container >::Entry >, + // Storage : former::CollectionAdd< Entry = < collection_tools::Vec< String > as former::Collection >::Entry >, Storage = Vec< String >, Context = Struct1Former< Definition >, - End = Struct1FormerAssignVec1End< Definition >, + End = Struct1SubformCollectionVec1End< Definition >, >, - Struct1FormerAssignVec1End< Definition > : former::FormingEnd + Struct1SubformCollectionVec1End< Definition > : former::FormingEnd < < collection_tools::Vec< String > as former::EntityToDefinitionTypes< Self, Self > >::Types >, { - Former2::former_begin( None, Some( self ), Struct1FormerAssignVec1End::< Definition >::default() ) + Former2::former_begin( None, Some( self ), Struct1SubformCollectionVec1End::< Definition >::default() ) } #[ inline( always ) ] - pub fn vec_1( self ) -> former::ContainerFormer:: + pub fn vec_1( self ) -> former::CollectionFormer:: < String, - former::VectorDefinition< String, Self, Self, Struct1FormerAssignVec1End< Definition > >, + former::VectorDefinition< String, Self, Self, Struct1SubformCollectionVec1End< Definition > >, > where - former::VectorDefinition< String, Self, Self, Struct1FormerAssignVec1End< Definition > > : former::FormerDefinition + former::VectorDefinition< String, Self, Self, Struct1SubformCollectionVec1End< Definition > > : former::FormerDefinition < - // Storage : former::ContainerAdd< Entry = < collection_tools::Vec< String > as former::Container >::Entry >, + // Storage : former::CollectionAdd< Entry = < collection_tools::Vec< String > as former::Collection >::Entry >, Storage = Vec< String >, Context = Struct1Former< Definition >, - End = Struct1FormerAssignVec1End< Definition >, + End = Struct1SubformCollectionVec1End< Definition >, >, - Struct1FormerAssignVec1End< Definition > : former::FormingEnd + Struct1SubformCollectionVec1End< Definition > : former::FormingEnd < < collection_tools::Vec< String > as former::EntityToDefinitionTypes< Self, Self > >::Types >, { - self._vec_1_assign::< former::ContainerFormer:: + self._vec_1_assign::< former::CollectionFormer:: < String, - former::VectorDefinition< String, Self, Self, Struct1FormerAssignVec1End< Definition > >, + former::VectorDefinition< String, Self, Self, Struct1SubformCollectionVec1End< Definition > >, > > () } @@ -391,46 +389,46 @@ where where Former2 : former::FormerBegin < - former::HashMapDefinition< String, String, Self, Self, Struct1FormerAssignHashmap1End< Definition > >, + former::HashMapDefinition< String, String, Self, Self, Struct1SubformCollectionHashmap1End< Definition > >, >, - former::HashMapDefinition< String, String, Self, Self, Struct1FormerAssignHashmap1End< Definition > > : former::FormerDefinition + former::HashMapDefinition< String, String, Self, Self, Struct1SubformCollectionHashmap1End< Definition > > : former::FormerDefinition < - // Storage : former::ContainerAdd< Entry = < collection_tools::HashMap< String, String > as former::Container >::Entry >, + // Storage : former::CollectionAdd< Entry = < collection_tools::HashMap< String, String > as former::Collection >::Entry >, Storage = collection_tools::HashMap< String, String >, Context = Struct1Former< Definition >, - End = Struct1FormerAssignHashmap1End< Definition >, + End = Struct1SubformCollectionHashmap1End< Definition >, >, - Struct1FormerAssignHashmap1End< Definition > : former::FormingEnd + Struct1SubformCollectionHashmap1End< Definition > : former::FormingEnd < < collection_tools::HashMap< String, String > as former::EntityToDefinitionTypes< Self, Self > >::Types >, { - Former2::former_begin( None, Some( self ), Struct1FormerAssignHashmap1End::< Definition >::default() ) + Former2::former_begin( None, Some( self ), Struct1SubformCollectionHashmap1End::< Definition >::default() ) } #[ inline( always ) ] - pub fn hashmap_1( self ) -> former::ContainerFormer:: + pub fn hashmap_1( self ) -> former::CollectionFormer:: < ( String, String ), - former::HashMapDefinition< String, String, Self, Self, Struct1FormerAssignHashmap1End< Definition > >, + former::HashMapDefinition< String, String, Self, Self, Struct1SubformCollectionHashmap1End< Definition > >, > where - former::HashMapDefinition< String, String, Self, Self, Struct1FormerAssignHashmap1End< Definition > > : former::FormerDefinition + former::HashMapDefinition< String, String, Self, Self, Struct1SubformCollectionHashmap1End< Definition > > : former::FormerDefinition < - // Storage : former::ContainerAdd< Entry = < collection_tools::HashMap< String, String > as former::Container >::Entry >, + // Storage : former::CollectionAdd< Entry = < collection_tools::HashMap< String, String > as former::Collection >::Entry >, Storage = collection_tools::HashMap< String, String >, Context = Struct1Former< Definition >, - End = Struct1FormerAssignHashmap1End< Definition >, + End = Struct1SubformCollectionHashmap1End< Definition >, >, - Struct1FormerAssignHashmap1End< Definition > : former::FormingEnd + Struct1SubformCollectionHashmap1End< Definition > : former::FormingEnd < < collection_tools::HashMap< String, String > as former::EntityToDefinitionTypes< Self, Self > >::Types >, { - self._hashmap_1_assign::< former::ContainerFormer:: + self._hashmap_1_assign::< former::CollectionFormer:: < ( String, String ), - former::HashMapDefinition< String, String, Self, Self, Struct1FormerAssignHashmap1End< Definition > >, + former::HashMapDefinition< String, String, Self, Self, Struct1SubformCollectionHashmap1End< Definition > >, > > () } @@ -439,46 +437,46 @@ where where Former2 : former::FormerBegin < - former::HashSetDefinition< String, Self, Self, Struct1FormerAssignHashset1End< Definition > >, + former::HashSetDefinition< String, Self, Self, Struct1SubformCollectionHashset1End< Definition > >, >, - former::HashSetDefinition< String, Self, Self, Struct1FormerAssignHashset1End< Definition > > : former::FormerDefinition + former::HashSetDefinition< String, Self, Self, Struct1SubformCollectionHashset1End< Definition > > : former::FormerDefinition < - // Storage : former::ContainerAdd< Entry = < collection_tools::HashSet< String > as former::Container >::Entry >, + // Storage : former::CollectionAdd< Entry = < collection_tools::HashSet< String > as former::Collection >::Entry >, Storage = collection_tools::HashSet< String >, Context = Struct1Former< Definition >, - End = Struct1FormerAssignHashset1End< Definition >, + End = Struct1SubformCollectionHashset1End< Definition >, >, - Struct1FormerAssignHashset1End< Definition > : former::FormingEnd + Struct1SubformCollectionHashset1End< Definition > : former::FormingEnd < < collection_tools::HashSet< String > as former::EntityToDefinitionTypes< Self, Self > >::Types >, { - Former2::former_begin( None, Some( self ), Struct1FormerAssignHashset1End::< Definition >::default() ) + Former2::former_begin( None, Some( self ), Struct1SubformCollectionHashset1End::< Definition >::default() ) } #[ inline( always ) ] - pub fn hashset_1( self ) -> former::ContainerFormer:: + pub fn hashset_1( self ) -> former::CollectionFormer:: < String, - former::HashSetDefinition< String, Self, Self, Struct1FormerAssignHashset1End< Definition > >, + former::HashSetDefinition< String, Self, Self, Struct1SubformCollectionHashset1End< Definition > >, > where - former::HashSetDefinition< String, Self, Self, Struct1FormerAssignHashset1End< Definition > > : former::FormerDefinition + former::HashSetDefinition< String, Self, Self, Struct1SubformCollectionHashset1End< Definition > > : former::FormerDefinition < - // Storage : former::ContainerAdd< Entry = < collection_tools::HashSet< String > as former::Container >::Entry >, + // Storage : former::CollectionAdd< Entry = < collection_tools::HashSet< String > as former::Collection >::Entry >, Storage = collection_tools::HashSet< String >, Context = Struct1Former< Definition >, - End = Struct1FormerAssignHashset1End< Definition >, + End = Struct1SubformCollectionHashset1End< Definition >, >, - Struct1FormerAssignHashset1End< Definition > : former::FormingEnd + Struct1SubformCollectionHashset1End< Definition > : former::FormingEnd < < collection_tools::HashSet< String > as former::EntityToDefinitionTypes< Self, Self > >::Types >, { - self._hashset_1_assign::< former::ContainerFormer:: + self._hashset_1_assign::< former::CollectionFormer:: < String, - former::HashSetDefinition< String, Self, Self, Struct1FormerAssignHashset1End< Definition > >, + former::HashSetDefinition< String, Self, Self, Struct1SubformCollectionHashset1End< Definition > >, > > () } @@ -540,12 +538,12 @@ where // = former assign end -pub struct Struct1FormerAssignVec1End< Definition > +pub struct Struct1SubformCollectionVec1End< Definition > { _phantom : core::marker::PhantomData< ( Definition, ) >, } -impl Default for Struct1FormerAssignVec1End< Definition > +impl Default for Struct1SubformCollectionVec1End< Definition > { #[ inline( always ) ] fn default() -> Self @@ -563,7 +561,7 @@ impl< Definition > former::FormingEnd < former::VectorDefinitionTypes< String, Struct1Former< Definition >, Struct1Former< Definition > > > -for Struct1FormerAssignVec1End< Definition > +for Struct1SubformCollectionVec1End< Definition > where Definition : former::FormerDefinition< Storage = Struct1FormerStorage >, Definition::Types : former::FormerDefinitionTypes< Storage = Struct1FormerStorage >, @@ -575,7 +573,7 @@ where let mut super_former = super_former.unwrap(); if let Some( ref mut field ) = super_former.storage.vec_1 { - former::ContainerAssign::assign( field, storage ); + former::CollectionAssign::assign( field, storage ); } else { @@ -585,12 +583,12 @@ where } } -pub struct Struct1FormerAssignHashmap1End +pub struct Struct1SubformCollectionHashmap1End { _phantom : core::marker::PhantomData<(Definition,)>, } -impl Default for Struct1FormerAssignHashmap1End +impl Default for Struct1SubformCollectionHashmap1End { #[ inline( always ) ] fn default() -> Self @@ -604,7 +602,7 @@ impl Default for Struct1FormerAssignHashmap1End impl< Definition, > former::FormingEnd < former::HashMapDefinitionTypes< String, String, Struct1Former< Definition >, Struct1Former< Definition > > > -for Struct1FormerAssignHashmap1End< Definition > +for Struct1SubformCollectionHashmap1End< Definition > where Definition : former::FormerDefinition< Storage = Struct1FormerStorage >, Definition::Types : former::FormerDefinitionTypes< Storage = Struct1FormerStorage >, @@ -616,7 +614,7 @@ where let mut super_former = super_former.unwrap(); if let Some( ref mut field ) = super_former.storage.hashmap_1 { - former::ContainerAssign::assign( field, storage ); + former::CollectionAssign::assign( field, storage ); } else { @@ -626,12 +624,12 @@ where } } -pub struct Struct1FormerAssignHashset1End +pub struct Struct1SubformCollectionHashset1End { _phantom : core::marker::PhantomData<(Definition,)>, } -impl Default for Struct1FormerAssignHashset1End +impl Default for Struct1SubformCollectionHashset1End { #[ inline( always ) ] fn default() -> Self @@ -645,7 +643,7 @@ impl Default for Struct1FormerAssignHashset1End impl< Definition, > former::FormingEnd < former::HashSetDefinitionTypes< String, Struct1Former< Definition >, Struct1Former< Definition > > > -for Struct1FormerAssignHashset1End< Definition > +for Struct1SubformCollectionHashset1End< Definition > where Definition : former::FormerDefinition< Storage = Struct1FormerStorage >, Definition::Types : former::FormerDefinitionTypes< Storage = Struct1FormerStorage >, @@ -657,7 +655,7 @@ where let mut super_former = super_former.unwrap(); if let Some( ref mut field ) = super_former.storage.hashset_1 { - former::ContainerAssign::assign( field, storage ); + former::CollectionAssign::assign( field, storage ); } else { @@ -669,4 +667,4 @@ where // == end of generated -include!( "./only_test/containers_with_subformer.rs" ); +include!( "./only_test/collections_with_subformer.rs" ); diff --git a/module/core/former/tests/inc/former_tests/a_containers_scalar.rs b/module/core/former/tests/inc/former_tests/subform_collection_basic_scalar.rs similarity index 88% rename from module/core/former/tests/inc/former_tests/a_containers_scalar.rs rename to module/core/former/tests/inc/former_tests/subform_collection_basic_scalar.rs index 4b3efafb88..266e622ab8 100644 --- a/module/core/former/tests/inc/former_tests/a_containers_scalar.rs +++ b/module/core/former/tests/inc/former_tests/subform_collection_basic_scalar.rs @@ -20,4 +20,4 @@ pub struct Struct1 // == end of generated -include!( "./only_test/containers_without_subformer.rs" ); +include!( "./only_test/collections_without_subformer.rs" ); diff --git a/module/core/former/tests/inc/former_tests/subformer_container_custom.rs b/module/core/former/tests/inc/former_tests/subform_collection_custom.rs similarity index 92% rename from module/core/former/tests/inc/former_tests/subformer_container_custom.rs rename to module/core/former/tests/inc/former_tests/subform_collection_custom.rs index 58f3a72356..9c42715133 100644 --- a/module/core/former/tests/inc/former_tests/subformer_container_custom.rs +++ b/module/core/former/tests/inc/former_tests/subform_collection_custom.rs @@ -4,9 +4,9 @@ use super::*; use collection_tools::HashSet; -// == define custom containers +// == define custom collections -// Custom container that logs additions +// Custom collection that logs additions #[ derive( Debug, PartialEq ) ] pub struct LoggingSet< K > where @@ -57,7 +57,7 @@ where } } -impl< K > former::Container for LoggingSet< K > +impl< K > former::Collection for LoggingSet< K > where K : core::cmp::Eq + core::hash::Hash, { @@ -72,7 +72,7 @@ where } -impl< K > former::ContainerAdd for LoggingSet< K > +impl< K > former::CollectionAdd for LoggingSet< K > where K : core::cmp::Eq + core::hash::Hash, { @@ -85,7 +85,7 @@ where } -impl< K > former::ContainerAssign for LoggingSet< K > +impl< K > former::CollectionAssign for LoggingSet< K > where K : core::cmp::Eq + core::hash::Hash, { @@ -99,7 +99,7 @@ where } } -impl< K > former::ContainerValToEntry< K > for LoggingSet< K > +impl< K > former::CollectionValToEntry< K > for LoggingSet< K > where K : core::cmp::Eq + core::hash::Hash, { @@ -230,15 +230,15 @@ where // = subformer pub type LoggingSetAsSubformer< K, Context, Formed, End > = -former::ContainerFormer::< K, LoggingSetDefinition< K, Context, Formed, End > >; +former::CollectionFormer::< K, LoggingSetDefinition< K, Context, Formed, End > >; -// == use custom container +// == use custom collection /// Parent required for the template. #[ derive( Debug, Default, PartialEq, the_module::Former ) ] pub struct Parent { - #[ container ] + #[ subform_collection ] children : LoggingSet< i32 >, } diff --git a/module/core/former/tests/inc/former_tests/subformer_container_implicit.rs b/module/core/former/tests/inc/former_tests/subform_collection_implicit.rs similarity index 78% rename from module/core/former/tests/inc/former_tests/subformer_container_implicit.rs rename to module/core/former/tests/inc/former_tests/subform_collection_implicit.rs index 55b91e69de..101e5cd210 100644 --- a/module/core/former/tests/inc/former_tests/subformer_container_implicit.rs +++ b/module/core/former/tests/inc/former_tests/subform_collection_implicit.rs @@ -17,8 +17,8 @@ pub struct Child // #[ derive( Debug, Default, PartialEq ) ] pub struct Parent { - // #[ container( definition = former::VectorDefinition ) ] - #[ container ] + // #[ subform_collection( definition = former::VectorDefinition ) ] + #[ subform_collection ] children : Vec< Child >, } @@ -26,4 +26,4 @@ pub struct Parent // == end of generated -include!( "./only_test/subformer_container.rs" ); +include!( "./only_test/subform_collection.rs" ); diff --git a/module/core/former/tests/inc/former_tests/subformer_container_manual.rs b/module/core/former/tests/inc/former_tests/subform_collection_manual.rs similarity index 57% rename from module/core/former/tests/inc/former_tests/subformer_container_manual.rs rename to module/core/former/tests/inc/former_tests/subform_collection_manual.rs index 82811c38eb..ee30f941b8 100644 --- a/module/core/former/tests/inc/former_tests/subformer_container_manual.rs +++ b/module/core/former/tests/inc/former_tests/subform_collection_manual.rs @@ -16,12 +16,12 @@ pub struct Child // #[ derive( Debug, Default, PartialEq ) ] pub struct Parent { - // #[ container( definition = former::VectorDefinition ) ] + // #[ subform_collection( definition = former::VectorDefinition ) ] #[ scalar( setter = false ) ] children : Vec< Child >, } -// == begin of generated for Parent in context of attribute container( former::VectorDefinition ) ] +// == begin of generated for Parent in context of attribute collection( former::VectorDefinition ) ] #[ automatically_derived ] impl< Definition, > ParentFormer< Definition, > @@ -30,34 +30,34 @@ where { #[ inline( always ) ] - pub fn _children_container_former< Former2 >( self ) -> Former2 + pub fn _children_subform_collection< Former2 >( self ) -> Former2 where - Former2 : former::FormerBegin< former::VectorDefinition< Child, Self, Self, ParentFormerAssignChildrenEnd< Definition >, > >, + Former2 : former::FormerBegin< former::VectorDefinition< Child, Self, Self, ParentSubformCollectionChildrenEnd< Definition >, > >, { - Former2::former_begin( None, Some( self ), ParentFormerAssignChildrenEnd::< Definition >::default() ) + Former2::former_begin( None, Some( self ), ParentSubformCollectionChildrenEnd::< Definition >::default() ) } #[ inline( always ) ] - pub fn children( self ) -> former::ContainerFormer:: + pub fn children( self ) -> former::CollectionFormer:: < Child, - former::VectorDefinition< Child, Self, Self, ParentFormerAssignChildrenEnd< Definition >, > + former::VectorDefinition< Child, Self, Self, ParentSubformCollectionChildrenEnd< Definition >, > > { - self._children_container_former::< former::ContainerFormer::< Child, former::VectorDefinition< Child, Self, Self, ParentFormerAssignChildrenEnd< Definition >, > > >() + self._children_subform_collection::< former::CollectionFormer::< Child, former::VectorDefinition< Child, Self, Self, ParentSubformCollectionChildrenEnd< Definition >, > > >() } } // -#[ doc = r"Callback to return original former after forming of container for `vec_1` is done. Callback replace content of container assigning new content from subformer's storage." ] -pub struct ParentFormerAssignChildrenEnd< Definition > +#[ doc = r"Callback to return original former after forming of collection for `vec_1` is done. Callback replace content of collection assigning new content from subformer's storage." ] +pub struct ParentSubformCollectionChildrenEnd< Definition > { _phantom : core::marker::PhantomData< ( Definition, ) >, } -impl< Definition > Default for ParentFormerAssignChildrenEnd< Definition > +impl< Definition > Default for ParentSubformCollectionChildrenEnd< Definition > { #[ inline( always ) ] @@ -78,7 +78,7 @@ impl< Definition, > former::FormingEnd Vec< Child > as former::EntityToDefinitionTypes< ParentFormer< Definition, >, ParentFormer< Definition, > > >::Types > -for ParentFormerAssignChildrenEnd< Definition > +for ParentSubformCollectionChildrenEnd< Definition > where Definition : former::FormerDefinition< Storage = ParentFormerStorage< > >, { @@ -94,7 +94,7 @@ where let mut super_former = super_former.unwrap(); if let Some( ref mut field ) = super_former.storage.children { - former::ContainerAssign::assign( field, storage ); + former::CollectionAssign::assign( field, storage ); } else { @@ -104,6 +104,6 @@ where } } -// == end of generated for Parent in context of attribute container( former::VectorDefinition ) ] +// == end of generated for Parent in context of attribute collection( former::VectorDefinition ) ] -include!( "./only_test/subformer_container.rs" ); +include!( "./only_test/subform_collection.rs" ); diff --git a/module/core/former/tests/inc/former_tests/subformer_container_named.rs b/module/core/former/tests/inc/former_tests/subform_collection_named.rs similarity index 86% rename from module/core/former/tests/inc/former_tests/subformer_container_named.rs rename to module/core/former/tests/inc/former_tests/subform_collection_named.rs index 75ce8845b6..1f06c4b6ea 100644 --- a/module/core/former/tests/inc/former_tests/subformer_container_named.rs +++ b/module/core/former/tests/inc/former_tests/subform_collection_named.rs @@ -16,7 +16,7 @@ pub struct Child // #[ derive( Debug, Default, PartialEq ) ] pub struct Parent { - #[ container( name = children2 ) ] + #[ subform_collection( name = children2 ) ] children : Vec< Child >, } @@ -29,7 +29,7 @@ where pub fn children( self ) -> &'static str { r#" - Scalar setter `children` should not be generated by default if container is used. + Scalar setter `children` should not be generated by default if collection is used. It can only be generated if req "# } @@ -40,4 +40,4 @@ where // == end of generated -include!( "./only_test/subformer_container_children2.rs" ); +include!( "./only_test/subform_collection_children2.rs" ); diff --git a/module/core/former/tests/inc/former_tests/subformer_basic.rs b/module/core/former/tests/inc/former_tests/subform_collection_playground.rs similarity index 89% rename from module/core/former/tests/inc/former_tests/subformer_basic.rs rename to module/core/former/tests/inc/former_tests/subform_collection_playground.rs index 11f5a65779..0e3782a900 100644 --- a/module/core/former/tests/inc/former_tests/subformer_basic.rs +++ b/module/core/former/tests/inc/former_tests/subform_collection_playground.rs @@ -31,6 +31,7 @@ pub struct Property< Name > code : isize, } +// zzz : implement derive new /// generated by new impl< Name > Property< Name > { @@ -54,7 +55,7 @@ where { pub name : String, pub subject : String, - #[ container( definition = former::HashMapDefinition ) ] + #[ subform_collection( definition = former::HashMapDefinition ) ] pub properties : collection_tools::HashMap< K, Property< K > >, } @@ -66,7 +67,7 @@ where Definition::Storage : former::StoragePreform, { - /// Inserts a key-value pair into the map. Make a new container if it was not made so far. + /// Inserts a key-value pair into the map. Make a new collection if it was not made so far. #[ inline( always ) ] pub fn property< Name, Description, Code > ( mut self, name : Name, description : Description, code : Code ) -> Self @@ -102,10 +103,10 @@ where K : core::hash::Hash + std::cmp::Eq, { pub parameter1 : String, - #[ container( definition = former::HashMapDefinition ) ] + #[ subform_collection( definition = former::HashMapDefinition ) ] pub commands : collection_tools::HashMap< String, Child< K > >, } // == -include!( "./only_test/subformer_basic.rs" ); +include!( "./only_test/subform_basic.rs" ); diff --git a/module/core/former/tests/inc/former_tests/subformer_container_setter_off.rs b/module/core/former/tests/inc/former_tests/subform_collection_setter_off.rs similarity index 70% rename from module/core/former/tests/inc/former_tests/subformer_container_setter_off.rs rename to module/core/former/tests/inc/former_tests/subform_collection_setter_off.rs index 5f3ca56708..fa01385e98 100644 --- a/module/core/former/tests/inc/former_tests/subformer_container_setter_off.rs +++ b/module/core/former/tests/inc/former_tests/subform_collection_setter_off.rs @@ -17,7 +17,7 @@ pub struct Child // #[ derive( Debug, Default, PartialEq ) ] pub struct Parent { - #[ container( setter = false ) ] + #[ subform_collection( setter = false ) ] // #[ scalar( setter = false ) ] children : Vec< Child >, } @@ -31,21 +31,21 @@ where pub fn children( self ) -> &'static str { r#" - Scalar setter `children` should not be generated by default if container is used. + Scalar setter `children` should not be generated by default if collection is used. It can only be generated if req "# } #[ inline( always ) ] - pub fn children2( self ) -> former::ContainerFormer:: + pub fn children2( self ) -> former::CollectionFormer:: < Child, - former::VectorDefinition< Child, Self, Self, ParentFormerAssignChildrenEnd< Definition >, > + former::VectorDefinition< Child, Self, Self, ParentSubformCollectionChildrenEnd< Definition >, > > { - self._children_container_former::< _ >() + self._children_subform_collection::< _ >() } } -include!( "./only_test/subformer_container_children2.rs" ); +include!( "./only_test/subform_collection_children2.rs" ); diff --git a/module/core/former/tests/inc/former_tests/subformer_container_setter_on.rs b/module/core/former/tests/inc/former_tests/subform_collection_setter_on.rs similarity index 59% rename from module/core/former/tests/inc/former_tests/subformer_container_setter_on.rs rename to module/core/former/tests/inc/former_tests/subform_collection_setter_on.rs index 83233366cf..0f35a3c2a0 100644 --- a/module/core/former/tests/inc/former_tests/subformer_container_setter_on.rs +++ b/module/core/former/tests/inc/former_tests/subform_collection_setter_on.rs @@ -17,9 +17,9 @@ pub struct Child // #[ derive( Debug, Default, PartialEq ) ] pub struct Parent { - // Such parameters switch off generation of front-end container setter and switch on scalar setter. + // Such parameters switch off generation of front-end collection setter and switch on scalar setter. // Without explicit scalar_setter( true ) scalar setter is not generated. - #[ subform( setter = false ) ] + #[ subform_entry( setter = false ) ] #[ scalar( setter = true ) ] children : Vec< Child >, } @@ -30,16 +30,16 @@ where { #[ inline( always ) ] - pub fn children2( self ) -> former::ContainerFormer:: + pub fn children2( self ) -> former::CollectionFormer:: < Child, - former::VectorDefinition< Child, Self, Self, ParentFormerAssignChildrenEnd< Definition >, > + former::VectorDefinition< Child, Self, Self, ParentSubformCollectionChildrenEnd< Definition >, > > { - self._children_container_former::< _ >() + self._children_subform_collection::< _ >() } } -include!( "./only_test/subformer_scalar_children.rs" ); -include!( "./only_test/subformer_container_children2.rs" ); +include!( "./only_test/subform_scalar_children.rs" ); +include!( "./only_test/subform_collection_children2.rs" ); diff --git a/module/core/former/tests/inc/former_tests/subformer_subform.rs b/module/core/former/tests/inc/former_tests/subform_entry.rs similarity index 82% rename from module/core/former/tests/inc/former_tests/subformer_subform.rs rename to module/core/former/tests/inc/former_tests/subform_entry.rs index e112d38ecd..063fec5dc4 100644 --- a/module/core/former/tests/inc/former_tests/subformer_subform.rs +++ b/module/core/former/tests/inc/former_tests/subform_entry.rs @@ -17,7 +17,7 @@ pub struct Child // #[ derive( Debug, Default, PartialEq ) ] pub struct Parent { - #[ subform( setter = false ) ] + #[ subform_entry( setter = false ) ] children : Vec< Child >, } @@ -29,14 +29,14 @@ where #[ inline( always ) ] pub fn child( self, name : &str ) -> ChildAsSubformer< Self, impl ChildAsSubformerEnd< Self > > { - self._children_add::< ChildFormer< _ >, _, >() + self._children_subform_entry::< ChildFormer< _ >, _, >() .name( name ) } #[ inline( always ) ] pub fn _child( self ) -> ChildAsSubformer< Self, impl ChildAsSubformerEnd< Self > > { - self._children_add + self._children_subform_entry ::< < Child as former::EntityToFormer< _ > >::Former, _, >() } @@ -46,4 +46,4 @@ where // == end of generated -include!( "./only_test/subformer_subform_child.rs" ); +include!( "./only_test/subform_entry_child.rs" ); diff --git a/module/core/former/tests/inc/former_tests/subformer_subform_hashmap.rs b/module/core/former/tests/inc/former_tests/subform_entry_hashmap.rs similarity index 98% rename from module/core/former/tests/inc/former_tests/subformer_subform_hashmap.rs rename to module/core/former/tests/inc/former_tests/subform_entry_hashmap.rs index 2c0ad7e8d7..48bcddf617 100644 --- a/module/core/former/tests/inc/former_tests/subformer_subform_hashmap.rs +++ b/module/core/former/tests/inc/former_tests/subform_entry_hashmap.rs @@ -19,7 +19,7 @@ pub struct Child // #[ derive( Debug, PartialEq ) ] pub struct Parent { - #[ subform ] + #[ subform_entry ] command : HashMap< String, Child >, } diff --git a/module/core/former/tests/inc/former_tests/subformer_subform_hashmap_custom.rs b/module/core/former/tests/inc/former_tests/subform_entry_hashmap_custom.rs similarity index 89% rename from module/core/former/tests/inc/former_tests/subformer_subform_hashmap_custom.rs rename to module/core/former/tests/inc/former_tests/subform_entry_hashmap_custom.rs index 175197fab8..1b1dce6e63 100644 --- a/module/core/former/tests/inc/former_tests/subformer_subform_hashmap_custom.rs +++ b/module/core/former/tests/inc/former_tests/subform_entry_hashmap_custom.rs @@ -19,7 +19,7 @@ pub struct Child // #[ derive( Debug, PartialEq ) ] pub struct Parent { - #[ subform( setter = false ) ] + #[ subform_entry( setter = false ) ] command : HashMap< String, Child >, } @@ -31,7 +31,7 @@ where // more generic version #[ inline( always ) ] - pub fn _children_add_with_closure< Former2, Definition2, Types2 >( self ) -> + pub fn _children_subform_entry_with_closure< Former2, Definition2, Types2 >( self ) -> Former2 where Types2 : former::FormerDefinitionTypes @@ -63,10 +63,10 @@ where } if let Some( ref mut children ) = super_former.storage.command { - former::ContainerAdd::add + former::CollectionAdd::add ( children, - < < HashMap< String, Child > as former::Container >::Val as former::ValToEntry< HashMap< String, Child > > > + < < HashMap< String, Child > as former::Collection >::Val as former::ValToEntry< HashMap< String, Child > > > ::val_to_entry( former::StoragePreform::preform( substorage ) ) ); } @@ -75,15 +75,15 @@ where Former2::former_begin( None, Some( self ), former::FormingEndClosure::new( on_end ) ) } - // reuse _command_add + // reuse _command_subform_entry #[ inline( always ) ] pub fn command( self, name : &str ) -> ChildAsSubformer< Self, impl ChildAsSubformerEnd< Self > > { - self._command_add::< ChildFormer< _ >, _, >() + self._command_subform_entry::< ChildFormer< _ >, _, >() .name( name ) } - // that's how you should do custom subformer setters if you can't reuse _command_add + // that's how you should do custom subformer setters if you can't reuse _command_subform_entry #[ inline( always ) ] pub fn command2( self, name : &str ) -> ChildAsSubformer< Self, impl ChildAsSubformerEnd< Self > > { @@ -97,12 +97,12 @@ where super_former.storage.command = Some( Default::default() ); } - // add instance to the container + // add instance to the collection super_former.storage.command.as_mut().unwrap() .entry( preformed.name.clone() ) .or_insert( preformed.clone() ); - // custom logic to add two instances to the container + // custom logic to add two instances to the collection super_former.storage.command.as_mut().unwrap() .entry( format!( "{}_2", preformed.name ) ) .or_insert( preformed.clone() ); diff --git a/module/core/former/tests/inc/former_tests/subformer_subform_manual.rs b/module/core/former/tests/inc/former_tests/subform_entry_manual.rs similarity index 73% rename from module/core/former/tests/inc/former_tests/subformer_subform_manual.rs rename to module/core/former/tests/inc/former_tests/subform_entry_manual.rs index dd75b254c0..2a210b97bb 100644 --- a/module/core/former/tests/inc/former_tests/subformer_subform_manual.rs +++ b/module/core/former/tests/inc/former_tests/subform_entry_manual.rs @@ -15,8 +15,8 @@ pub struct Child // #[ derive( Debug, Default, PartialEq ) ] pub struct Parent { - // #[ container( definition = former::VectorDefinition ) ] - // #[ subform ] + // #[ subform_collection( definition = former::VectorDefinition ) ] + // #[ subform_entry ] #[ scalar( setter = false ) ] children : Vec< Child >, } @@ -30,7 +30,7 @@ where { #[ inline( always ) ] - pub fn _children_add_with_closure< Former2, Definition2, Types2 >( self ) -> + pub fn _children_subform_entry_with_closure< Former2, Definition2, Types2 >( self ) -> Former2 where Types2 : former::FormerDefinitionTypes @@ -62,10 +62,10 @@ where } if let Some( ref mut children ) = super_former.storage.children { - former::ContainerAdd::add + former::CollectionAdd::add ( children, - < < Vec< Child > as former::Container >::Val as former::ValToEntry< Vec< Child > > > + < < Vec< Child > as former::Collection >::Val as former::ValToEntry< Vec< Child > > > ::val_to_entry( former::StoragePreform::preform( substorage ) ) ); } @@ -74,14 +74,12 @@ where Former2::former_begin( None, Some( self ), former::FormingEndClosure::new( on_end ) ) } - // < < #field_ty as former::Container >::Val as former::ValToEntry< #field_ty > > - // less generic, but more concise way to define custom subform setter #[ inline( always ) ] pub fn child( self, name : &str ) -> ChildAsSubformer< Self, impl ChildAsSubformerEnd< Self > > { - self._children_add + self._children_subform_entry ::< ChildFormer< _ >, _, >() .name( name ) } @@ -90,24 +88,24 @@ where // pub fn _child( self ) -> // ChildAsSubformer< Self, impl ChildAsSubformerEnd< Self > > // { - // self._children_add + // self._children_subform_entry // ::< < Child as former::EntityToFormer< _ > >::Former, _, >() // } // it is generated #[ inline( always ) ] pub fn _child( self ) -> - < < Vec< Child > as former::Container >::Entry as former::EntityToFormer + < < Vec< Child > as former::Collection >::Entry as former::EntityToFormer < - // ChildFormerDefinition< Self, Self, ParentFormerAddChildrenEnd< Definition > >, + // ChildFormerDefinition< Self, Self, ParentSubformEntryChildrenEnd< Definition > >, < - < Vec< Child > as former::Container >::Entry as former::EntityToDefinition< Self, Self, ParentFormerAddChildrenEnd< Definition > > + < Vec< Child > as former::Collection >::Entry as former::EntityToDefinition< Self, Self, ParentSubformEntryChildrenEnd< Definition > > >::Definition, > >::Former { - self._children_add - ::< < < Vec< Child > as former::Container >::Entry as former::EntityToFormer< _ > >::Former, _, >() + self._children_subform_entry + ::< < < Vec< Child > as former::Collection >::Entry as former::EntityToFormer< _ > >::Former, _, >() } } @@ -121,12 +119,12 @@ where { #[ inline( always ) ] - pub fn _children_add< Former2, Definition2 >( self ) -> + pub fn _children_subform_entry< Former2, Definition2 >( self ) -> Former2 where Definition2 : former::FormerDefinition < - End = ParentFormerAddChildrenEnd< Definition >, + End = ParentSubformEntryChildrenEnd< Definition >, Storage = < Child as former::EntityToStorage >::Storage, Formed = Self, Context = Self, @@ -139,19 +137,19 @@ where >, Former2 : former::FormerBegin< Definition2 >, { - Former2::former_begin( None, Some( self ), ParentFormerAddChildrenEnd::default() ) + Former2::former_begin( None, Some( self ), ParentSubformEntryChildrenEnd::default() ) } } -/// Handles the completion of and element of subformer's container. -pub struct ParentFormerAddChildrenEnd< Definition > +/// Handles the completion of and element of subformer's collection. +pub struct ParentSubformEntryChildrenEnd< Definition > { _phantom : core::marker::PhantomData< fn( Definition ) >, } impl< Definition > Default -for ParentFormerAddChildrenEnd< Definition > +for ParentSubformEntryChildrenEnd< Definition > { #[ inline( always ) ] fn default() -> Self @@ -164,7 +162,7 @@ for ParentFormerAddChildrenEnd< Definition > } impl< Types2, Definition > former::FormingEnd< Types2, > -for ParentFormerAddChildrenEnd< Definition > +for ParentSubformEntryChildrenEnd< Definition > where Definition : former::FormerDefinition < @@ -172,7 +170,7 @@ where >, Types2 : former::FormerDefinitionTypes < - Storage = < < Vec< Child > as former::Container >::Entry as former::EntityToStorage >::Storage, + Storage = < < Vec< Child > as former::Collection >::Entry as former::EntityToStorage >::Storage, Formed = ParentFormer< Definition >, Context = ParentFormer< Definition >, >, @@ -193,7 +191,7 @@ where } if let Some( ref mut fields ) = super_former.storage.children { - former::ContainerAdd::add( fields, former::StoragePreform::preform( substorage ) ); + former::CollectionAdd::add( fields, former::StoragePreform::preform( substorage ) ); } super_former } @@ -201,4 +199,4 @@ where // == end of generated for Parent in context of attribute subform -include!( "./only_test/subformer_subform_child.rs" ); +include!( "./only_test/subform_entry_child.rs" ); diff --git a/module/core/former/tests/inc/former_tests/subformer_subform_named.rs b/module/core/former/tests/inc/former_tests/subform_entry_named.rs similarity index 89% rename from module/core/former/tests/inc/former_tests/subformer_subform_named.rs rename to module/core/former/tests/inc/former_tests/subform_entry_named.rs index e834e8b30d..37e2c79d55 100644 --- a/module/core/former/tests/inc/former_tests/subformer_subform_named.rs +++ b/module/core/former/tests/inc/former_tests/subform_entry_named.rs @@ -17,7 +17,7 @@ pub struct Child // #[ derive( Debug, Default, PartialEq ) ] pub struct Parent { - #[ subform( name = _child ) ] + #[ subform_entry( name = _child ) ] children : Vec< Child >, } @@ -40,7 +40,7 @@ where pub fn child( self, name : &str ) -> ChildAsSubformer< Self, impl ChildAsSubformerEnd< Self > > { - self._children_add + self._children_subform_entry ::< ChildFormer< _ >, _, >() .name( name ) } @@ -49,7 +49,7 @@ where // pub fn _child( self ) -> // ChildAsSubformer< Self, impl ChildAsSubformerEnd< Self > > // { - // self._children_add + // self._children_subform_entry // ::< < Child as former::EntityToFormer< _ > >::Former, _, >() // } @@ -59,4 +59,4 @@ where // == end of generated -include!( "./only_test/subformer_subform_child.rs" ); +include!( "./only_test/subform_entry_child.rs" ); diff --git a/module/core/former/tests/inc/former_tests/subformer_subform_named_manual.rs b/module/core/former/tests/inc/former_tests/subform_entry_named_manual.rs similarity index 69% rename from module/core/former/tests/inc/former_tests/subformer_subform_named_manual.rs rename to module/core/former/tests/inc/former_tests/subform_entry_named_manual.rs index c169a74d79..3d0542c592 100644 --- a/module/core/former/tests/inc/former_tests/subformer_subform_named_manual.rs +++ b/module/core/former/tests/inc/former_tests/subform_entry_named_manual.rs @@ -17,7 +17,7 @@ pub struct Child // #[ derive( Debug, Default, PartialEq ) ] pub struct Parent { - #[ subform ] + #[ subform_entry ] // #[ scalar( setter = false ) ] children : Vec< Child >, } @@ -33,7 +33,7 @@ where pub fn child( self, name : &str ) -> ChildAsSubformer< Self, impl ChildAsSubformerEnd< Self > > { - self._children_add + self._children_subform_entry ::< ChildFormer< _ >, _, >() .name( name ) } @@ -42,23 +42,23 @@ where // pub fn _child( self ) -> // ChildAsSubformer< Self, impl ChildAsSubformerEnd< Self > > // { - // self._children_add + // self._children_subform_entry // ::< < Child as former::EntityToFormer< _ > >::Former, _, >() // } #[ inline( always ) ] pub fn _child( self ) -> - < < Vec< Child > as former::Container >::Entry as former::EntityToFormer + < < Vec< Child > as former::Collection >::Entry as former::EntityToFormer < - // ChildFormerDefinition< Self, Self, ParentFormerAddChildrenEnd< Definition > >, + // ChildFormerDefinition< Self, Self, ParentSubformEntryChildrenEnd< Definition > >, < - < Vec< Child > as former::Container >::Entry as former::EntityToDefinition< Self, Self, ParentFormerAddChildrenEnd< Definition > > + < Vec< Child > as former::Collection >::Entry as former::EntityToDefinition< Self, Self, ParentSubformEntryChildrenEnd< Definition > > >::Definition, > >::Former { - self._children_add - ::< < < Vec< Child > as former::Container >::Entry as former::EntityToFormer< _ > >::Former, _, >() + self._children_subform_entry + ::< < < Vec< Child > as former::Collection >::Entry as former::EntityToFormer< _ > >::Former, _, >() } } @@ -69,4 +69,4 @@ where // == end of generated for Parent in context of attribute subform -include!( "./only_test/subformer_subform_child.rs" ); +include!( "./only_test/subform_entry_child.rs" ); diff --git a/module/core/former/tests/inc/former_tests/subformer_subform_setter_off.rs b/module/core/former/tests/inc/former_tests/subform_entry_setter_off.rs similarity index 87% rename from module/core/former/tests/inc/former_tests/subformer_subform_setter_off.rs rename to module/core/former/tests/inc/former_tests/subform_entry_setter_off.rs index e5a2f9eb61..ae08d3c05c 100644 --- a/module/core/former/tests/inc/former_tests/subformer_subform_setter_off.rs +++ b/module/core/former/tests/inc/former_tests/subform_entry_setter_off.rs @@ -17,7 +17,7 @@ pub struct Child // #[ derive( Debug, Default, PartialEq ) ] pub struct Parent { - #[ subform( setter = false ) ] + #[ subform_entry( setter = false ) ] children : Vec< Child >, } @@ -39,11 +39,11 @@ where pub fn children2( self, name : &str ) -> ChildAsSubformer< Self, impl ChildAsSubformerEnd< Self > > { - self._children_add + self._children_subform_entry ::< ChildFormer< _ >, _, >() .name( name ) } } -include!( "./only_test/subformer_subform_children2.rs" ); +include!( "./only_test/subform_entry_children2.rs" ); diff --git a/module/core/former/tests/inc/former_tests/subformer_subform_setter_on.rs b/module/core/former/tests/inc/former_tests/subform_entry_setter_on.rs similarity index 83% rename from module/core/former/tests/inc/former_tests/subformer_subform_setter_on.rs rename to module/core/former/tests/inc/former_tests/subform_entry_setter_on.rs index 29378ff208..fd5608463e 100644 --- a/module/core/former/tests/inc/former_tests/subformer_subform_setter_on.rs +++ b/module/core/former/tests/inc/former_tests/subform_entry_setter_on.rs @@ -19,7 +19,7 @@ pub struct Parent { // Such parameters switch off generation of front-end subform setter and switch on scalar setter. // Without explicit scalar_setter( true ) scalar setter is not generated. - #[ subform( setter = false ) ] + #[ subform_entry( setter = false ) ] #[ scalar( setter = true ) ] children : Vec< Child >, } @@ -33,12 +33,12 @@ where pub fn children2( self, name : &str ) -> ChildAsSubformer< Self, impl ChildAsSubformerEnd< Self > > { - self._children_add + self._children_subform_entry ::< ChildFormer< _ >, _, >() .name( name ) } } -include!( "./only_test/subformer_scalar_children.rs" ); -include!( "./only_test/subformer_subform_children2.rs" ); +include!( "./only_test/scalar_children.rs" ); +include!( "./only_test/subform_entry_children2.rs" ); diff --git a/module/core/former/tests/inc/former_tests/subform_scalar.rs b/module/core/former/tests/inc/former_tests/subform_scalar.rs new file mode 100644 index 0000000000..bf081269fb --- /dev/null +++ b/module/core/former/tests/inc/former_tests/subform_scalar.rs @@ -0,0 +1,28 @@ +#![ allow( dead_code ) ] + +use super::*; + +/// Child +#[ derive( Debug, Default, PartialEq, the_module::Former ) ] +pub struct Child +{ + name : String, + data : bool, +} + +/// Parent + +#[ derive( Debug, Default, PartialEq, the_module::Former ) ] +// #[ debug ] +// #[ derive( Debug, Default, PartialEq ) ] +pub struct Parent +{ + #[ subform_scalar ] + child : Child, +} + +// == begin of generated + +// == end of generated + +include!( "./only_test/subform_scalar.rs" ); diff --git a/module/core/former/tests/inc/former_tests/subform_scalar_manual.rs b/module/core/former/tests/inc/former_tests/subform_scalar_manual.rs new file mode 100644 index 0000000000..d0d8ef9608 --- /dev/null +++ b/module/core/former/tests/inc/former_tests/subform_scalar_manual.rs @@ -0,0 +1,140 @@ +#![ allow( dead_code ) ] + +use super::*; + +/// Child +#[ derive( Debug, Default, PartialEq, the_module::Former ) ] +pub struct Child +{ + name : String, + data : bool, +} + +/// Parent + +#[ derive( Debug, Default, PartialEq, the_module::Former ) ] +// #[ debug ] +// #[ derive( Debug, Default, PartialEq ) ] +pub struct Parent +{ + #[ scalar( setter = false ) ] + // #[ scalar_subform ] + child : Child, +} + +impl< Definition > ParentFormer< Definition > +where + Definition : former::FormerDefinition< Storage = < Parent as former::EntityToStorage >::Storage >, +{ + + #[ inline( always ) ] + pub fn _child_subform_scalar< Former2, Definition2 >( self ) -> + Former2 + where + Definition2 : former::FormerDefinition + < + End = ParentFormerSubformScalarChildEnd< Definition >, + Storage = < Child as former::EntityToStorage >::Storage, + Formed = Self, + Context = Self, + >, + Definition2::Types : former::FormerDefinitionTypes + < + Storage = < Child as former::EntityToStorage >::Storage, + Formed = Self, + Context = Self, + >, + Former2 : former::FormerBegin< Definition2 >, + { + Former2::former_begin( None, Some( self ), ParentFormerSubformScalarChildEnd::default() ) + } + +} + +impl< Definition > ParentFormer< Definition > +where + Definition : former::FormerDefinition< Storage = < Parent as former::EntityToStorage >::Storage >, +{ + + #[ inline( always ) ] + pub fn child( self ) -> + ChildAsSubformer< Self, impl ChildAsSubformerEnd< Self > > + { + self._child_subform_scalar + ::< < Child as former::EntityToFormer< _ > >::Former, _, >() + } + +} + +// = end + +/// Represents the endpoint for the forming process of a scalar field managed by a subformer within a `Parent` 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. +/// Essentially, this end action integrates the individually formed scalar value back into the parent structure. +/// +/// ## Type Parameters +/// +/// - `Definition`: The type that defines the former setup for the `Parent` entity, influencing storage and behavior during forming. +/// +/// ## Parameters of `call` +/// +/// - `substorage`: Storage type specific to the `Child`, containing the newly formed scalar value. +/// - `super_former`: An optional context of the `ParentFormer`, which will receive the value. The function ensures +/// that this context is not `None` and inserts the formed value into the designated field within `Parent`'s storage. +/// + +pub struct ParentFormerSubformScalarChildEnd< Definition > +{ + _phantom : core::marker::PhantomData< fn( Definition ) >, +} + +impl< Definition > Default +for ParentFormerSubformScalarChildEnd< Definition > +{ + #[ inline( always ) ] + fn default() -> Self + { + Self + { + _phantom : core::marker::PhantomData, + } + } +} + +impl< Types2, Definition > former::FormingEnd< Types2, > +for ParentFormerSubformScalarChildEnd< Definition > +where + Definition : former::FormerDefinition + < + Storage = < Parent as former::EntityToStorage >::Storage, + >, + Types2 : former::FormerDefinitionTypes + < + Storage = < Child as former::EntityToStorage >::Storage, + Formed = ParentFormer< Definition >, + Context = ParentFormer< Definition >, + >, +{ + #[ inline( always ) ] + fn call + ( + &self, + substorage : Types2::Storage, + super_former : core::option::Option< Types2::Context >, + ) + -> Types2::Formed + { + let mut super_former = super_former.unwrap(); + debug_assert!( super_former.storage.child.is_none() ); + super_former.storage.child = Some( ::core::convert::Into::into( former::StoragePreform::preform( substorage ) ) ); + super_former + } +} + +// == begin of generated + +// == end of generated + +include!( "./only_test/subform_scalar.rs" ); diff --git a/module/core/former/tests/inc/former_tests/subform_scalar_name.rs b/module/core/former/tests/inc/former_tests/subform_scalar_name.rs new file mode 100644 index 0000000000..87a0d52ded --- /dev/null +++ b/module/core/former/tests/inc/former_tests/subform_scalar_name.rs @@ -0,0 +1,73 @@ +#![ allow( dead_code ) ] + +use super::*; + +/// Child +#[ derive( Debug, Default, PartialEq, the_module::Former ) ] +pub struct Child +{ + name : String, + data : bool, +} + +/// Parent + +#[ derive( Debug, Default, PartialEq, the_module::Former ) ] +// #[ debug ] +// #[ derive( Debug, Default, PartialEq ) ] +pub struct Parent +{ + #[ subform_scalar( name = child2 ) ] + child : Child, +} + +impl< Definition > ParentFormer< Definition > +where + Definition : former::FormerDefinition< Storage = < Parent as former::EntityToStorage >::Storage >, +{ + + pub fn child() + { + } + + #[ inline( always ) ] + pub fn child3( self ) -> + ChildAsSubformer< Self, impl ChildAsSubformerEnd< Self > > + { + self._child_subform_scalar + ::< < Child as former::EntityToFormer< _ > >::Former, _, >() + } + +} + +// == begin of generated + +// == end of generated + +#[ test ] +fn subforme_scalar_2() +{ + + let got = Parent::former() + .child2().name( "a" ).data( true ).end() + .form(); + + let exp = Parent { child : Child { name : "a".to_string(), data : true } }; + a_id!( got, exp ); + +} + +#[ test ] +fn subforme_scalar_3() +{ + + let got = Parent::former() + .child3().name( "a" ).data( true ).end() + .form(); + + let exp = Parent { child : Child { name : "a".to_string(), data : true } }; + a_id!( got, exp ); + +} + +// qqq : write tests similar to `subform_all` which apply attributes `scalar`, `subform_entry` and `subform_scalar` on the same field and check all three attribtues don't interfere with each other diff --git a/module/core/former/tests/inc/mod.rs b/module/core/former/tests/inc/mod.rs index 069cbec9e2..9f94e5f37d 100644 --- a/module/core/former/tests/inc/mod.rs +++ b/module/core/former/tests/inc/mod.rs @@ -9,27 +9,22 @@ mod former_tests #[ allow( unused_imports ) ] use super::*; - #[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] - mod container_former_common; - #[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] - mod container_former_vec; - #[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] - mod container_former_hashset; - #[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] - mod container_former_hashmap; + // = basic mod a_basic_manual; mod a_basic; mod a_primitives_manual; mod a_primitives; - mod a_containers_scalar; + mod subform_collection_basic_scalar; #[ cfg( not( feature = "no_std" ) ) ] - mod a_containers_manual; + mod subform_collection_basic_manual; #[ cfg( not( feature = "no_std" ) ) ] - mod a_containers; + mod subform_collection_basic; - mod attribute_default_container; + // = attribute + + mod attribute_default_collection; mod attribute_default_primitive; mod attribute_default_conflict; mod attribute_storage_with_end; @@ -39,13 +34,7 @@ mod former_tests mod attribute_alias; mod attribute_feature; - mod string_slice_manual; - mod string_slice; - mod unsigned_primitive_types; - mod default_user_type; - mod user_type_no_default; - mod user_type_no_debug; - mod visibility; + // = name collision mod name_collision_former_hashmap_without_parameter; mod name_collision_former_vector_without_parameter; @@ -54,6 +43,8 @@ mod former_tests mod name_collision_end; mod name_collision_on_end; + // = parametrization + #[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] mod parametrized_struct_manual; #[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] @@ -63,46 +54,82 @@ mod former_tests mod parametrized_field; mod parametrized_field_where; + mod parametrized_slice_manual; + mod parametrized_slice; + + // = etc + + mod unsigned_primitive_types; + mod default_user_type; + mod user_type_no_default; + mod user_type_no_debug; + mod visibility; + + // = collection former + #[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] - mod subformer_basic; + mod collection_former_common; + #[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] + mod collection_former_vec; + #[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] + mod collection_former_hashset; + #[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] + mod collection_former_hashmap; + + // = subform collection + #[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] + mod subform_collection_playground; + #[ cfg( any( not( feature = "no_std" ) ) ) ] + mod subform_collection; + #[ cfg( any( not( feature = "no_std" ) ) ) ] + mod subform_collection_manual; + #[ cfg( any( not( feature = "no_std" ) ) ) ] + mod subform_collection_implicit; #[ cfg( any( not( feature = "no_std" ) ) ) ] - mod subformer_container; + mod subform_collection_setter_off; #[ cfg( any( not( feature = "no_std" ) ) ) ] - mod subformer_container_manual; + mod subform_collection_named; #[ cfg( any( not( feature = "no_std" ) ) ) ] - mod subformer_container_implicit; + mod subform_collection_custom; + + // = subform scalar + #[ cfg( any( not( feature = "no_std" ) ) ) ] - mod subformer_container_setter_off; + mod subform_scalar_manual; #[ cfg( any( not( feature = "no_std" ) ) ) ] - mod subformer_container_named; + mod subform_scalar; #[ cfg( any( not( feature = "no_std" ) ) ) ] - mod subformer_container_custom; + mod subform_scalar_name; + + // = subform entry #[ cfg( any( not( feature = "no_std" ) ) ) ] - mod subformer_subform; + mod subform_entry; #[ cfg( any( not( feature = "no_std" ) ) ) ] - mod subformer_subform_manual; + mod subform_entry_manual; #[ cfg( any( not( feature = "no_std" ) ) ) ] - mod subformer_subform_named; + mod subform_entry_named; #[ cfg( any( not( feature = "no_std" ) ) ) ] - mod subformer_subform_named_manual; + mod subform_entry_named_manual; #[ cfg( any( not( feature = "no_std" ) ) ) ] - mod subformer_subform_setter_off; + mod subform_entry_setter_off; #[ cfg( any( not( feature = "no_std" ) ) ) ] - mod subformer_subform_setter_on; + mod subform_entry_setter_on; #[ cfg( any( not( feature = "no_std" ) ) ) ] - mod subformer_subform_hashmap; + mod subform_entry_hashmap; #[ cfg( any( not( feature = "no_std" ) ) ) ] - mod subformer_subform_hashmap_custom; + mod subform_entry_hashmap_custom; + + // = subform all : scalar, subform_scalar, subform_entry, subform_collection #[ cfg( any( not( feature = "no_std" ) ) ) ] - mod subformer_subform_and_container; + mod subform_all; #[ cfg( any( not( feature = "no_std" ) ) ) ] - mod subformer_subform_and_container_private; + mod subform_all_private; #[ cfg( any( not( feature = "no_std" ) ) ) ] - mod subformer_subform_and_container_parametrized; + mod subform_all_parametrized; } diff --git a/module/core/former_meta/src/derive_former.rs b/module/core/former_meta/src/derive_former.rs index b934d9cbf9..3ad56cca8d 100644 --- a/module/core/former_meta/src/derive_former.rs +++ b/module/core/former_meta/src/derive_former.rs @@ -4,7 +4,7 @@ use iter_tools::{ Itertools, process_results }; use macro_tools::{ attr, diag, generic_params, generic_args, typ, derive, Result }; use proc_macro2::TokenStream; -// qqq : implement interfaces for other containers +// qqq : implement interfaces for other collections mod field; use field::*; @@ -43,6 +43,8 @@ use struct_attrs::*; pub fn mutator ( + stru : &syn::Ident, + original_input : &proc_macro::TokenStream, mutator : &AttributeMutator, former_definition_types : &syn::Ident, former_definition_types_generics_impl : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, @@ -76,7 +78,7 @@ pub fn mutator = Example of custom mutator impl< {} > former::FormerMutator -for {} < {} > +for {former_definition_types} < {} > where {} {{ @@ -88,11 +90,16 @@ where }} "#, format!( "{}", qt!{ #former_definition_types_generics_impl } ), - former_definition_types, format!( "{}", qt!{ #former_definition_types_generics_ty } ), format!( "{}", qt!{ #former_definition_types_generics_where } ), ); - println!( "{hint}" ); + // println!( "{hint}" ); + let about = format! + ( +r#"derive : Former +structure : {stru}"#, + ); + diag::report_print( about, original_input, hint ); }; Ok( former_mutator_code ) @@ -296,6 +303,7 @@ specific needs of the broader forming context. It mandates the implementation of field.former_field_setter ( &stru, + &original_input, &struct_generics_impl, &struct_generics_ty, &struct_generics_where, @@ -304,7 +312,6 @@ specific needs of the broader forming context. It mandates the implementation of &former_generics_ty, &former_generics_where, &former_storage, - &original_input, ), )}).multiunzip(); @@ -315,6 +322,8 @@ specific needs of the broader forming context. It mandates the implementation of let former_mutator_code = mutator ( + &stru, + &original_input, &struct_attrs.mutator, &former_definition_types, &former_definition_types_generics_impl, diff --git a/module/core/former_meta/src/derive_former/field.rs b/module/core/former_meta/src/derive_former/field.rs index a38cdead95..b6bf5a9ce3 100644 --- a/module/core/former_meta/src/derive_former/field.rs +++ b/module/core/former_meta/src/derive_former/field.rs @@ -33,13 +33,14 @@ storage_field_optional storage_field_preform storage_field_name former_field_setter -subform_setter -container_setter scalar_setter +subform_entry_setter +subform_collection_setter scalar_setter_name -container_setter_name -subform_setter_name +subform_scalar_setter_name, +subform_collection_setter_name +subform_entry_setter_name scalar_setter_required */ @@ -75,7 +76,7 @@ scalar_setter_required /// /// Generate fields for initializer of a struct setting each field to `None`. /// - /// Used for initializing a Container, where on initialization all fields are None. User can alter them through builder pattern + /// Used for initializing a Collection, where on initialization all fields are None. User can alter them through builder pattern /// /// ### Basic use-case. of output /// @@ -102,7 +103,7 @@ scalar_setter_required /// /// Generate field of the former for a field of the structure /// - /// Used to generate a Container + /// Used to generate a Collection /// /// ### Basic use-case. of output /// @@ -306,7 +307,7 @@ scalar_setter_required /// /// This function is responsible for dynamically creating code that allows for the building /// or modifying of fields within a `Former`-enabled struct or enum. It supports different - /// types of setters based on the field attributes, such as scalar setters, container setters, + /// types of setters based on the field attributes, such as scalar setters, collection setters, /// and subform setters. /// /// # Returns @@ -319,7 +320,7 @@ scalar_setter_required /// /// The generation of setters is dependent on the attributes of the field: /// - **Scalar Setters**: Created for basic data types and simple fields. - /// - **Container Setters**: Generated when the field is annotated to behave as a container, + /// - **Collection Setters**: Generated when the field is annotated to behave as a collection, /// supporting operations like adding or replacing elements. /// - **Subform Setters**: Generated for fields annotated as subforms, allowing for nested /// forming processes where a field itself can be formed using a dedicated former. @@ -330,6 +331,7 @@ scalar_setter_required ( &self, stru : &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 >, struct_generics_where : &syn::punctuated::Punctuated< syn::WherePredicate, syn::token::Comma >, @@ -338,21 +340,45 @@ scalar_setter_required former_generics_ty : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, former_generics_where : &syn::punctuated::Punctuated< syn::WherePredicate, syn::token::Comma >, former_storage : &syn::Ident, - original_input : &proc_macro::TokenStream, ) -> Result< ( TokenStream, TokenStream ) > { + + // scalar setter let namespace_code = qt! {}; let setters_code = self.scalar_setter ( + stru, former, former_storage, + original_input, ); - // container setter - let ( setters_code, namespace_code ) = if let Some( _ ) = &self.attrs.container + // subform scalar setter + let ( setters_code, namespace_code ) = if self.attrs.subform_scalar.is_some() { - let ( setters_code2, namespace_code2 ) = self.container_setter + let ( setters_code2, namespace_code2 ) = self.subform_scalar_setter + ( + stru, + former, + former_storage, + former_generics_ty, + struct_generics_impl, + struct_generics_ty, + struct_generics_where, + original_input, + )?; + ( qt! { #setters_code #setters_code2 }, qt! { #namespace_code #namespace_code2 } ) + } + else + { + ( setters_code, namespace_code ) + }; + + // subform collection setter + let ( setters_code, namespace_code ) = if let Some( _ ) = &self.attrs.subform_collection + { + let ( setters_code2, namespace_code2 ) = self.subform_collection_setter ( stru, former, @@ -369,10 +395,10 @@ scalar_setter_required ( setters_code, namespace_code ) }; - // subform setter - let ( setters_code, namespace_code ) = if self.attrs.subform.is_some() + // subform entry setter + let ( setters_code, namespace_code ) = if self.attrs.subform_entry.is_some() { - let ( setters_code2, namespace_code2 ) = self.subform_setter + let ( setters_code2, namespace_code2 ) = self.subform_entry_setter ( stru, former, @@ -381,6 +407,7 @@ scalar_setter_required struct_generics_impl, struct_generics_ty, struct_generics_where, + original_input, )?; ( qt! { #setters_code #setters_code2 }, qt! { #namespace_code #namespace_code2 } ) } @@ -393,17 +420,428 @@ scalar_setter_required Ok( ( setters_code, namespace_code ) ) } - /// Generates setter functions for subforms within a container structure in a builder pattern. + /// + /// Generate a single scalar setter for the 'field_ident' with the 'setter_name' name. + /// + /// Used as a helper function for former_field_setter(), which generates alias setters + /// + /// # Example of generated code + /// + /// ```ignore + /// #[ doc = "Setter for the 'int_1' field." ] + /// #[ inline ] + /// pub fn int_1< Src >( mut self, src : Src ) -> Self + /// where + /// Src : ::core::convert::Into< i32 >, + /// { + /// debug_assert!( self.int_1.is_none() ); + /// self.storage.int_1 = ::core::option::Option::Some( ::core::convert::Into::into( src ) ); + /// self + /// } + /// ``` + + #[ inline ] + pub fn scalar_setter + ( + &self, + stru : &syn::Ident, + former : &syn::Ident, + former_storage : &syn::Ident, + original_input : &proc_macro::TokenStream, + ) + -> TokenStream + { + let field_ident = self.ident; + let typ = self.non_optional_ty; + let setter_name = self.scalar_setter_name(); + let attr = self.attrs.scalar.as_ref(); + + if attr.is_some() && attr.unwrap().hint + { + let hint = format! + ( + r#" +impl< Definition > {former}< Definition > +where + Definition : former::FormerDefinition< Storage = {former_storage} >, +{{ + #[ inline ] + pub fn {field_ident}< Src >( mut self, src : Src ) -> Self + where + Src : ::core::convert::Into< {0} >, + {{ + debug_assert!( self.storage.{field_ident}.is_none() ); + self.storage.{field_ident} = ::core::option::Option::Some( ::core::convert::Into::into( src ) ); + self + }} +}} + "#, + format!( "{}", qt!{ #typ } ), + ); + let about = format! + ( +r#"derive : Former +structure : {stru} +field : {field_ident}"#, + ); + diag::report_print( about, original_input, hint ); + } + + if !self.scalar_setter_required() + { + return qt! {}; + } + + let doc = format! + ( + "Scalar setter for the '{}' field.", + field_ident, + ); + + qt! + { + #[ doc = #doc ] + #[ inline ] + pub fn #setter_name< Src >( mut self, src : Src ) -> Self + where + Src : ::core::convert::Into< #typ >, + { + debug_assert!( self.storage.#field_ident.is_none() ); + self.storage.#field_ident = ::core::option::Option::Some( ::core::convert::Into::into( src ) ); + self + } + } + + } + + /// + /// Generate a collection setter for the 'field_ident' with the 'setter_name' name. + /// + /// See `tests/inc/former_tests/subform_collection_manual.rs` for example of generated code. + /// + + #[ inline ] + pub fn subform_collection_setter + ( + &self, + stru : &syn::Ident, + former : &syn::Ident, + former_storage : &syn::Ident, + former_generics_impl : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, + former_generics_ty : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, + former_generics_where : &syn::punctuated::Punctuated< syn::WherePredicate, syn::token::Comma >, + original_input : &proc_macro::TokenStream, + ) + -> Result< ( TokenStream, TokenStream ) > + { + let attr = self.attrs.subform_collection.as_ref().unwrap(); + let field_ident = &self.ident; + let field_typ = &self.non_optional_ty; + 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 : `former::VectorDefinition` + let subformer_definition = &attr.definition; + let subformer_definition = if subformer_definition.is_some() + { + qt! + { + #subformer_definition + < + #( #params, )* + Self, + Self, + #subform_collection_end< Definition >, + > + } + // former::VectorDefinition< String, Self, Self, Struct1SubformCollectionVec1End, > + } + else + { + qt! + { + < + #field_typ as former::EntityToDefinition< Self, Self, #subform_collection_end< Definition > > + >::Definition + } + // < Vec< String > as former::EntityToDefinition< Self, Self, Struct1SubformCollectionVec1End > >::Definition + }; + + let doc = format! + ( + "Collection setter for the '{}' field. Method {} unlike method {} accept custom collection subformer.", + field_ident, + subform_collection_name, + field_ident, + ); + + let setter1 = + qt! + { + + #[ doc = #doc ] + #[ inline( always ) ] + pub fn #subform_collection< Former2 >( self ) -> Former2 + where + Former2 : former::FormerBegin + < + #subformer_definition, + >, + #subformer_definition : former::FormerDefinition + < + // Storage : former::CollectionAdd< Entry = < #field_typ as former::Collection >::Entry >, + Storage = #field_typ, + Context = #former< #former_generics_ty >, + End = #subform_collection_end< Definition >, + >, + { + Former2::former_begin( None, Some( self ), #subform_collection_end::< Definition >::default() ) + } + + // #[ inline( always ) ] + // pub fn _hashset_1_assign< Former2 >( self ) -> Former2 + // where + // Former2 : former::FormerBegin + // < + // former::HashSetDefinition< String, Self, Self, Struct1SubformCollectionHashset1End< Definition > >, + // >, + // former::HashSetDefinition< String, Self, Self, Struct1SubformCollectionHashset1End< Definition > > : former::FormerDefinition + // < + // Storage : former::CollectionAdd< Entry = < collection_tools::HashSet< String > as former::Collection >::Entry >, + // Context = Struct1Former< Definition >, + // End = Struct1SubformCollectionHashset1End< Definition >, + // >, + // { + // Former2::former_begin( None, Some( self ), Struct1SubformCollectionHashset1End::< Definition >::default() ) + // } + + }; + + let setter_name = self.subform_collection_setter_name(); + let setter2 = if let Some( setter_name ) = setter_name + { + qt! + { + + #[ doc = #doc ] + #[ inline( always ) ] + pub fn #setter_name( self ) -> former::CollectionFormer:: + < + // ( #( #params, )* ), + < #field_typ as former::Collection >::Entry, + #subformer_definition, + > + where + #subformer_definition : former::FormerDefinition + < + // Storage : former::CollectionAdd< Entry = < #field_typ as former::Collection >::Entry >, + Storage = #field_typ, + Context = #former< #former_generics_ty >, + End = #subform_collection_end < Definition >, + >, + { + self.#subform_collection::< former::CollectionFormer:: + < + _, + _, + // ( #( #params, )* ), + // #subformer_definition, + > > () + } + + // #[ inline( always ) ] + // pub fn hashset_1( self ) -> former::CollectionFormer:: + // < + // String, + // former::HashSetDefinition< String, Self, Self, Struct1SubformCollectionHashset1End< Definition > >, + // > + // where + // former::HashSetDefinition< String, Self, Self, Struct1SubformCollectionHashset1End< Definition > > : former::FormerDefinition + // < + // Storage : former::CollectionAdd< Entry = < collection_tools::HashSet< String > as former::Collection >::Entry >, + // Context = Struct1Former< Definition >, + // End = Struct1SubformCollectionHashset1End< Definition >, + // >, + // { + // self._hashset_1_assign::< former::CollectionFormer:: + // < + // String, + // former::HashSetDefinition< String, Self, Self, Struct1SubformCollectionHashset1End< Definition > >, + // > > () + // } + + } + } + else + { + qt!{} + }; + + if attr.hint + { + let hint = 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. + +impl< Definition, > {former}< Definition, > +where + Definition : former::FormerDefinition< Storage = {former_storage} >, +{{ + + #[ inline( always ) ] + pub fn {field_ident}( self ) -> former::CollectionFormer:: + < + ( {0} ), + former::HashMapDefinition< {0} Self, Self, {subform_collection_end}< Definition >, > + // Replace `HashMapDefinition` with definition for your collection + > + {{ + self.{subform_collection}() + }} + +}} + "#, + format!( "{}", qt!{ #( #params, )* } ), + ); + let about = format! + ( +r#"derive : Former +structure : {stru} +field : {field_ident}"#, + ); + diag::report_print( about, original_input, hint ); + } + + let setters_code = qt! + { + #setter1 + #setter2 + }; + + // example : `former::VectorDefinition`` + let subformer_definition = &self.attrs.subform_collection.as_ref().unwrap().definition; + + let subform_collection_end_doc = format! + ( + r#" +A callback structure to manage the final stage of forming a `{0}` for the `{stru}` 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}` +with the new content generated during the subforming process. + "#, + format!( "{}", qt!{ #field_typ } ), + ); + + let subformer_definition_types = if let Some( ref _subformer_definition ) = subformer_definition + { + let subformer_definition_types_string = format!( "{}Types", qt!{ #subformer_definition } ); + let subformer_definition_types : syn::Type = syn::parse_str( &subformer_definition_types_string )?; + qt! + { + #subformer_definition_types + < + #( #params, )* + #former< #former_generics_ty >, + #former< #former_generics_ty >, + > + } + } + else + { + qt! + { + < + #field_typ as former::EntityToDefinitionTypes + < + #former< #former_generics_ty >, + #former< #former_generics_ty >, + > + >::Types + } + }; + + let r = qt! + { + + #[ doc = #subform_collection_end_doc ] + pub struct #subform_collection_end< Definition > + { + _phantom : core::marker::PhantomData< ( Definition, ) >, + } + + impl< Definition > Default + for #subform_collection_end< Definition > + { + + #[ inline( always ) ] + fn default() -> Self + { + Self + { + _phantom : core::marker::PhantomData, + } + } + + } + + #[ automatically_derived ] + impl< #former_generics_impl > former::FormingEnd + < + // VectorDefinitionTypes + #subformer_definition_types, + > + for #subform_collection_end< Definition > + where + #former_generics_where + { + #[ inline( always ) ] + fn call + ( + &self, + storage : #field_typ, + super_former : Option< #former< #former_generics_ty > >, + ) + -> #former< #former_generics_ty > + { + let mut super_former = super_former.unwrap(); + if let Some( ref mut field ) = super_former.storage.#field_ident + { + former::CollectionAssign::assign( field, storage ); + } + else + { + super_former.storage.#field_ident = Some( storage ); + } + super_former + } + } + + }; + + // tree_print!( r.as_ref().unwrap() ); + let namespace_code = r; + + Ok( ( setters_code, namespace_code ) ) + } + + /// Generates setter functions to subform entries of a collection. /// /// This function is a key component of the `former` crate's capability to dynamically create setters for manipulating - /// data within a nested container structure like a `HashMap` or a `Vec`. The setters facilitate the addition or - /// modification of entries within the container, directly from the parent former's context. + /// data within a nested collection structure like a `HashMap` or a `Vec`. The setters facilitate the addition or + /// modification of entries within the collection, directly from the parent former's context. /// - /// See `examples/subformer_subform_manual.rs` for example of generated code. + /// See `tests/inc/former_tests/subform_entry_manual.rs` for example of generated code. /// #[ inline ] - pub fn subform_setter + pub fn subform_entry_setter ( &self, stru : &syn::Ident, @@ -413,31 +851,29 @@ scalar_setter_required struct_generics_impl : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, struct_generics_ty : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, struct_generics_where : &syn::punctuated::Punctuated< syn::WherePredicate, syn::token::Comma >, + original_input : &proc_macro::TokenStream, ) -> Result< ( TokenStream, TokenStream ) > { - // if self.attrs.subform.is_none() - // { - // return Ok( qt!{ } ); - // } - use convert_case::{ Case, Casing }; let field_ident = self.ident; let field_typ = self.non_optional_ty; - let attr = self.attrs.subform.as_ref().unwrap(); + let entry_typ : &syn::Type = typ::parameter_first( field_typ )?; + + let attr = self.attrs.subform_entry.as_ref().unwrap(); // let params = typ::type_parameters( &self.non_optional_ty, .. ); - // example : `child` - let setter_name = self.subform_setter_name(); + // example : `children` + let setter_name = self.subform_entry_setter_name(); - // example : `ParentFormerAddChildrenEnd`` - let former_add_end_name = format!( "{}FormerAdd{}End", stru, field_ident.to_string().to_case( Case::Pascal ) ); - let former_add_end = syn::Ident::new( &former_add_end_name, field_ident.span() ); + // 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 : `_children_former` - let field_add_name = format!( "_{}_add", field_ident ); - let field_add = syn::Ident::new( &field_add_name, field_ident.span() ); + // 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 doc = format! ( @@ -447,7 +883,7 @@ Initiates the addition of {field_ident} to the `{stru}` entity using a dedicated 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 -handled by `{former_add_end}`, ensuring that the {field_ident} are properly integrated into the +handled by `{subform_entry_end}`, ensuring that the {field_ident} are properly integrated into the parent's structure once formed. # Returns @@ -464,24 +900,24 @@ allowing for dynamic and flexible construction of the `{stru}` entity's {field_i #[ doc = #doc ] #[ inline( always ) ] - pub fn #field_add< Former2, Definition2 >( self ) -> Former2 + pub fn #subform_entry< Former2, Definition2 >( self ) -> Former2 where Definition2 : former::FormerDefinition < - End = #former_add_end< Definition >, - Storage = < < #field_typ as former::Container >::Val as former::EntityToStorage >::Storage, + End = #subform_entry_end< Definition >, + Storage = < < #field_typ as former::Collection >::Val as former::EntityToStorage >::Storage, Formed = Self, Context = Self, >, Definition2::Types : former::FormerDefinitionTypes < - Storage = < < #field_typ as former::Container >::Val as former::EntityToStorage >::Storage, + Storage = < < #field_typ as former::Collection >::Val as former::EntityToStorage >::Storage, Formed = Self, Context = Self, >, Former2 : former::FormerBegin< Definition2 >, { - Former2::former_begin( None, Some( self ), #former_add_end::default() ) + Former2::former_begin( None, Some( self ), #subform_entry_end::default() ) } }; @@ -510,17 +946,17 @@ allowing for dynamic and flexible construction of the `{stru}` entity's {field_i #[ doc = #doc ] #[ inline( always ) ] pub fn #setter_name( self ) -> - < < #field_typ as former::Container >::Val as former::EntityToFormer + < < #field_typ as former::Collection >::Val as former::EntityToFormer < < - < #field_typ as former::Container >::Val as former::EntityToDefinition< Self, Self, #former_add_end < Definition > > + < #field_typ as former::Collection >::Val as former::EntityToDefinition< Self, Self, #subform_entry_end < Definition > > >::Definition, > >::Former // #as_subformer< Self, impl #as_subformer_end< Self > > { - self.#field_add - ::< < < #field_typ as former::Container >::Val as former::EntityToFormer< _ > >::Former, _, >() + self.#subform_entry + ::< < < #field_typ as former::Collection >::Val as former::EntityToFormer< _ > >::Former, _, >() // ::< #former< _ >, _, >() } } @@ -529,7 +965,7 @@ allowing for dynamic and flexible construction of the `{stru}` entity's {field_i // pub fn child( self ) -> // ChildAsSubformer< Self, impl ChildAsSubformerEnd< Self > > // { - // self._children_add + // self._children_subform_entry // ::< < Child as former::EntityToFormer< _ > >::Former, _, >() // } @@ -544,39 +980,41 @@ allowing for dynamic and flexible construction of the `{stru}` entity's {field_i let hint = format! ( r#" - /// Initializes and configures a subformer for adding named child entities. This method leverages an internal function /// to create and return a configured subformer instance. It allows for the dynamic addition of children with specific names, /// integrating them into the formation process of the parent entity. -impl< Definition > {}< Definition > +impl< Definition > {former}< Definition > where - Definition : former::FormerDefinition< Storage = {} >, + Definition : former::FormerDefinition< Storage = {former_storage} >, {{ #[ inline( always ) ] - pub fn {}( self ) -> ChildAsSubformer< Self, impl ChildAsSubformerEnd< Self > > + pub fn {field_ident}( self ) -> {0}AsSubformer< Self, impl {0}AsSubformerEnd< Self > > {{ - self.{}::< ChildFormer< _ >, _, >() + self.{subform_entry_name}::< {0}Former< _ >, _, >() }} - // Replace Child with name of type of element value. + // Replace {0} with name of type of entry value. }} "#, - former, - former_storage, - field_ident, - field_add_name, + format!( "{}", qt!{ #entry_typ } ), + ); + let about = format! + ( +r#"derive : Former +structure : {stru} +field : {field_ident}"#, ); - println!( "{hint}" ); + diag::report_print( about, original_input, hint ); } let doc = format! ( r#" -Implements the `FormingEnd` trait for `{former_add_end}` to handle the final -stage of the forming process for a `{stru}` container that contains `{0}` elements. +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. 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 @@ -610,13 +1048,13 @@ formation process of the `{stru}`. { #[ doc = #doc ] - pub struct #former_add_end< Definition > + pub struct #subform_entry_end< Definition > { _phantom : core::marker::PhantomData< fn( Definition ) >, } impl< Definition > Default - for #former_add_end< Definition > + for #subform_entry_end< Definition > { #[ inline( always ) ] fn default() -> Self @@ -629,7 +1067,7 @@ formation process of the `{stru}`. } impl< #struct_generics_impl Types2, Definition > former::FormingEnd< Types2, > - for #former_add_end< Definition > + for #subform_entry_end< Definition > where Definition : former::FormerDefinition < @@ -637,7 +1075,7 @@ formation process of the `{stru}`. >, Types2 : former::FormerDefinitionTypes < - Storage = < < #field_typ as former::Container >::Val as former::EntityToStorage >::Storage, + Storage = < < #field_typ as former::Collection >::Val as former::EntityToStorage >::Storage, Formed = #former< #former_generics_ty >, Context = #former< #former_generics_ty >, >, @@ -659,10 +1097,10 @@ formation process of the `{stru}`. } if let Some( ref mut field ) = super_former.storage.#field_ident { - former::ContainerAdd::add + former::CollectionAdd::add ( field, - < < #field_typ as former::Container >::Val as former::ValToEntry< #field_typ > > + < < #field_typ as former::Collection >::Val as former::ValToEntry< #field_typ > > ::val_to_entry( former::StoragePreform::preform( substorage ) ), ); } @@ -676,171 +1114,175 @@ formation process of the `{stru}`. Ok( ( setters_code, namespace_code ) ) } + /// Generates setter functions to subform scalar and all corresponding helpers. /// - /// Generate a container setter for the 'field_ident' with the 'setter_name' name. - /// - /// See `examples/subformer_container_manual.rs` for example of generated code. + /// See `tests/inc/former_tests/subform_scalar_manual.rs` for example of generated code. #[ inline ] - pub fn container_setter + pub fn subform_scalar_setter ( &self, stru : &syn::Ident, former : &syn::Ident, - former_storage : &syn::Ident, - former_generics_impl : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, + _former_storage : &syn::Ident, former_generics_ty : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, - former_generics_where : &syn::punctuated::Punctuated< syn::WherePredicate, syn::token::Comma >, + struct_generics_impl : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, + struct_generics_ty : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, + struct_generics_where : &syn::punctuated::Punctuated< syn::WherePredicate, syn::token::Comma >, original_input : &proc_macro::TokenStream, ) -> Result< ( TokenStream, TokenStream ) > { - let attr = self.attrs.container.as_ref().unwrap(); - let field_ident = &self.ident; - let field_typ = &self.non_optional_ty; - let params = typ::type_parameters( &field_typ, .. ); use convert_case::{ Case, Casing }; - let former_assign_end_name = format!( "{}FormerAssign{}End", stru, field_ident.to_string().to_case( Case::Pascal ) ); - let former_assign_end = syn::Ident::new( &former_assign_end_name, field_ident.span() ); - let field_assign_name = format!( "_{}_container_former", field_ident ); - let field_assign = syn::Ident::new( &field_assign_name, field_ident.span() ); + let field_ident = self.ident; + let field_typ = self.non_optional_ty; + let attr = self.attrs.subform_scalar.as_ref().unwrap(); + // let params = typ::type_parameters( &self.non_optional_ty, .. ); - // example : `former::VectorDefinition` - let subformer_definition = &attr.definition; - let subformer_definition = if subformer_definition.is_some() - { - qt! - { - #subformer_definition - < - #( #params, )* - Self, - Self, - #former_assign_end< Definition >, - > - } - // former::VectorDefinition< String, Self, Self, Struct1FormerAssignVec1End, > - } - else - { - qt! - { - < - #field_typ as former::EntityToDefinition< Self, Self, #former_assign_end< Definition > > - >::Definition - } - // < Vec< String > as former::EntityToDefinition< Self, Self, Struct1FormerAssignVec1End > >::Definition - }; + // 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 : `_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 doc = format! ( - "Container setter for the '{}' field. Method {} unlike method {} accept custom container subformer.", - field_ident, - field_assign_name, - field_ident, + r#" + +Initiates the scalar subformer for a `{0}` entity within a `{stru}`. + +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}`. + +## Type Parameters + +- `Former2`: Represents the specific former to be returned. +- `Definition2`: Defines the former's setup including its end action and storage specifics. + +## Returns + +- `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}` +is properly initialized with all necessary configurations, including the default end action for integration. + +## Usage + +This function is typically called internally by a more user-friendly method that abstracts away the complex +generics, providing a cleaner interface for initiating subform operations on scalar fields. + + "#, + format!( "{}", qt!{ #field_typ } ), ); - let setter1 = - qt! + let setters_code = qt! { #[ doc = #doc ] #[ inline( always ) ] - pub fn #field_assign< Former2 >( self ) -> Former2 + pub fn #subform_scalar< Former2, Definition2 >( self ) -> + Former2 where - Former2 : former::FormerBegin + Definition2 : former::FormerDefinition < - #subformer_definition, + End = #subform_scalar_end< Definition >, + Storage = < #field_typ as former::EntityToStorage >::Storage, + Formed = Self, + Context = Self, >, - #subformer_definition : former::FormerDefinition + Definition2::Types : former::FormerDefinitionTypes < - // Storage : former::ContainerAdd< Entry = < #field_typ as former::Container >::Entry >, - Storage = #field_typ, - Context = #former< #former_generics_ty >, - End = #former_assign_end< Definition >, + Storage = < #field_typ as former::EntityToStorage >::Storage, + Formed = Self, + Context = Self, >, + Former2 : former::FormerBegin< Definition2 >, { - Former2::former_begin( None, Some( self ), #former_assign_end::< Definition >::default() ) + Former2::former_begin( None, Some( self ), #subform_scalar_end::default() ) } // #[ inline( always ) ] - // pub fn _hashset_1_assign< Former2 >( self ) -> Former2 + // pub fn _child_scalar_subformer< Former2, Definition2 >( self ) -> + // Former2 // where - // Former2 : former::FormerBegin + // Definition2 : former::FormerDefinition // < - // former::HashSetDefinition< String, Self, Self, Struct1FormerAssignHashset1End< Definition > >, + // End = ParentFormerSubformScalarChildEnd< Definition >, + // Storage = < Child as former::EntityToStorage >::Storage, + // Formed = Self, + // Context = Self, // >, - // former::HashSetDefinition< String, Self, Self, Struct1FormerAssignHashset1End< Definition > > : former::FormerDefinition + // Definition2::Types : former::FormerDefinitionTypes // < - // Storage : former::ContainerAdd< Entry = < collection_tools::HashSet< String > as former::Container >::Entry >, - // Context = Struct1Former< Definition >, - // End = Struct1FormerAssignHashset1End< Definition >, + // Storage = < Child as former::EntityToStorage >::Storage, + // Formed = Self, + // Context = Self, // >, + // Former2 : former::FormerBegin< Definition2 >, // { - // Former2::former_begin( None, Some( self ), Struct1FormerAssignHashset1End::< Definition >::default() ) + // Former2::former_begin( None, Some( self ), ParentFormerSubformScalarChildEnd::default() ) // } }; - let setter_name = self.container_setter_name(); - let setter2 = if let Some( setter_name ) = setter_name + let setters_code = if attr.setter() { + + let doc = format! + ( + r#" +Provides a user-friendly interface to begin subforming a scalar `{0}` field within a `{stru}`. + +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}`. + + "#, + format!( "{}", qt!{ #field_typ } ), + ); + qt! { + #setters_code #[ doc = #doc ] #[ inline( always ) ] - pub fn #setter_name( self ) -> former::ContainerFormer:: - < - // ( #( #params, )* ), - < #field_typ as former::Container >::Entry, - #subformer_definition, - > - where - #subformer_definition : former::FormerDefinition + pub fn #setter_name( self ) -> + < #field_typ as former::EntityToFormer < - // Storage : former::ContainerAdd< Entry = < #field_typ as former::Container >::Entry >, - Storage = #field_typ, - Context = #former< #former_generics_ty >, - End = #former_assign_end < Definition >, - >, + < + #field_typ as former::EntityToDefinition< Self, Self, #subform_scalar_end < Definition > > + >::Definition, + > + >::Former { - self.#field_assign::< former::ContainerFormer:: - < - _, - _, - // ( #( #params, )* ), - // #subformer_definition, - > > () + self.#subform_scalar + ::< < #field_typ as former::EntityToFormer< _ > >::Former, _, >() } // #[ inline( always ) ] - // pub fn hashset_1( self ) -> former::ContainerFormer:: - // < - // String, - // former::HashSetDefinition< String, Self, Self, Struct1FormerAssignHashset1End< Definition > >, - // > - // where - // former::HashSetDefinition< String, Self, Self, Struct1FormerAssignHashset1End< Definition > > : former::FormerDefinition - // < - // Storage : former::ContainerAdd< Entry = < collection_tools::HashSet< String > as former::Container >::Entry >, - // Context = Struct1Former< Definition >, - // End = Struct1FormerAssignHashset1End< Definition >, - // >, + // pub fn child( self ) -> + // ChildAsSubformer< Self, impl ChildAsSubformerEnd< Self > > // { - // self._hashset_1_assign::< former::ContainerFormer:: - // < - // String, - // former::HashSetDefinition< String, Self, Self, Struct1FormerAssignHashset1End< Definition > >, - // > > () + // self._child_scalar_subformer + // ::< < Child as former::EntityToFormer< _ > >::Former, _, >() // } } + } else { - qt!{} + setters_code }; if attr.hint @@ -848,35 +1290,21 @@ formation process of the `{stru}`. let hint = format! ( r#" +/// Extends `{former}` to include a method that initializes and configures a subformer for the '{field_ident}' field. +/// This function demonstrates the dynamic addition of a named {field_ident}, leveraging a subformer to specify detailed properties. -/// The containr setter provides a container setter that returns a ContainerFormer tailored for managing a collection of child entities. It employs a generic container definition to facilitate operations on the entire collection, such as adding or updating elements. - -impl< Definition, > {}< Definition, > +impl< Definition > {former}< Definition > where - Definition : former::FormerDefinition< Storage = {} >, + Definition : former::FormerDefinition< Storage = < {stru} as former::EntityToStorage >::Storage >, {{ - #[ inline( always ) ] - pub fn {}( self ) -> former::ContainerFormer:: - < - ( {} ), - former::HashMapDefinition< {} Self, Self, {}< Definition >, > - // Replace `HashMapDefinition` with definition for your container - > + pub fn {field_ident}( self, name : &str ) -> {0}AsSubformer< Self, impl {0}AsSubformerEnd< Self > > {{ - self.{}() + self._{field_ident}_subform_scalar::< {0}Former< _ >, _, >().name( name ) }} - }} - "#, - former, - former_storage, - field_ident, - format!( "{}", qt!{ #( #params, )* } ), - format!( "{}", qt!{ #( #params, )* } ), - former_assign_end, - field_assign, + format!( "{}", qt!{ #field_typ } ), ); let about = format! ( @@ -887,68 +1315,42 @@ field : {field_ident}"#, diag::report_print( about, original_input, hint ); } - let setters_code = qt! - { - #setter1 - #setter2 - }; - - // example : `former::VectorDefinition`` - let subformer_definition = &self.attrs.container.as_ref().unwrap().definition; - - let former_assign_end_doc = format! + let doc = format! ( r#" -A callback structure to manage the final stage of forming a `{0}` for the `{stru}` container. -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}` -with the new content generated during the subforming process. +Represents the endpoint for the forming process of a scalar field managed by a subformer within a `{stru}` 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. +Essentially, this end action integrates the individually formed scalar value back into the parent structure. + +## Type Parameters + +- `Definition`: The type that defines the former setup for the `{stru}` 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. + "#, format!( "{}", qt!{ #field_typ } ), ); - let subformer_definition_types = if let Some( ref _subformer_definition ) = subformer_definition - { - let subformer_definition_types_string = format!( "{}Types", qt!{ #subformer_definition } ); - let subformer_definition_types : syn::Type = syn::parse_str( &subformer_definition_types_string )?; - qt! - { - #subformer_definition_types - < - #( #params, )* - #former< #former_generics_ty >, - #former< #former_generics_ty >, - > - } - } - else - { - qt! - { - < - #field_typ as former::EntityToDefinitionTypes - < - #former< #former_generics_ty >, - #former< #former_generics_ty >, - > - >::Types - } - }; - - let r = qt! + let namespace_code = qt! { - #[ doc = #former_assign_end_doc ] - pub struct #former_assign_end< Definition > + #[ doc = #doc ] + pub struct #subform_scalar_end< Definition > { - _phantom : core::marker::PhantomData< ( Definition, ) >, + _phantom : core::marker::PhantomData< fn( Definition ) >, } impl< Definition > Default - for #former_assign_end< Definition > + for #subform_scalar_end< Definition > { - #[ inline( always ) ] fn default() -> Self { @@ -957,141 +1359,93 @@ with the new content generated during the subforming process. _phantom : core::marker::PhantomData, } } - } - #[ automatically_derived ] - impl< #former_generics_impl > former::FormingEnd - < - // VectorDefinitionTypes - #subformer_definition_types, - > - for #former_assign_end< Definition > + impl< #struct_generics_impl Types2, Definition > former::FormingEnd< Types2, > + for #subform_scalar_end< Definition > where - #former_generics_where + Definition : former::FormerDefinition + < + Storage = < #stru < #struct_generics_ty > as former::EntityToStorage >::Storage, + >, + Types2 : former::FormerDefinitionTypes + < + Storage = < #field_typ as former::EntityToStorage >::Storage, + Formed = #former< #former_generics_ty >, + Context = #former< #former_generics_ty >, + >, + #struct_generics_where { #[ inline( always ) ] fn call ( &self, - storage : #field_typ, - super_former : Option< #former< #former_generics_ty > >, + substorage : Types2::Storage, + super_former : core::option::Option< Types2::Context >, ) - -> #former< #former_generics_ty > + -> Types2::Formed { let mut super_former = super_former.unwrap(); - if let Some( ref mut field ) = super_former.storage.#field_ident - { - former::ContainerAssign::assign( field, storage ); - } - else - { - super_former.storage.#field_ident = Some( storage ); - } + debug_assert!( super_former.storage.#field_ident.is_none() ); + super_former.storage.#field_ident = Some( ::core::convert::Into::into( former::StoragePreform::preform( substorage ) ) ); super_former } } - }; +// pub struct ParentFormerSubformScalarChildEnd< Definition > +// { +// _phantom : core::marker::PhantomData< fn( Definition ) >, +// } +// +// impl< Definition > Default +// for ParentFormerSubformScalarChildEnd< Definition > +// { +// #[ inline( always ) ] +// fn default() -> Self +// { +// Self +// { +// _phantom : core::marker::PhantomData, +// } +// } +// } +// +// impl< Types2, Definition > former::FormingEnd< Types2, > +// for ParentFormerSubformScalarChildEnd< Definition > +// where +// Definition : former::FormerDefinition +// < +// Storage = < Parent as former::EntityToStorage >::Storage, +// >, +// Types2 : former::FormerDefinitionTypes +// < +// Storage = < Child as former::EntityToStorage >::Storage, +// Formed = ParentFormer< Definition >, +// Context = ParentFormer< Definition >, +// >, +// { +// #[ inline( always ) ] +// fn call +// ( +// &self, +// substorage : Types2::Storage, +// super_former : core::option::Option< Types2::Context >, +// ) +// -> Types2::Formed +// { +// let mut super_former = super_former.unwrap(); +// debug_assert!( super_former.storage.child.is_none() ); +// super_former.storage.child = Some( ::core::convert::Into::into( former::StoragePreform::preform( substorage ) ) ); +// super_former +// } +// } - // tree_print!( r.as_ref().unwrap() ); - let namespace_code = r; + }; + // tree_print!( setters_code.as_ref().unwrap() ); Ok( ( setters_code, namespace_code ) ) } - /// - /// Generate a single scalar setter for the 'field_ident' with the 'setter_name' name. - /// - /// Used as a helper function for former_field_setter(), which generates alias setters - /// - /// # Example of generated code - /// - /// ```ignore - /// #[ doc = "Setter for the 'int_1' field." ] - /// #[ inline ] - /// pub fn int_1< Src >( mut self, src : Src ) -> Self - /// where - /// Src : ::core::convert::Into< i32 >, - /// { - /// debug_assert!( self.int_1.is_none() ); - /// self.storage.int_1 = ::core::option::Option::Some( ::core::convert::Into::into( src ) ); - /// self - /// } - /// ``` - - #[ inline ] - pub fn scalar_setter - ( - &self, - former : &syn::Ident, - former_storage : &syn::Ident, - ) - -> TokenStream - { - let field_ident = self.ident; - let typ = self.non_optional_ty; - let setter_name = self.scalar_setter_name(); - let attr = self.attrs.scalar.as_ref(); - - if attr.is_some() && attr.unwrap().hint - { - let hint = format! - ( - r#" - -impl< Definition > {}< Definition > -where - Definition : former::FormerDefinition< Storage = {} >, -{{ - #[ inline ] - pub fn {}< Src >( mut self, src : Src ) -> Self - where - Src : ::core::convert::Into< {} >, - {{ - debug_assert!( self.storage.{}.is_none() ); - self.storage.{} = ::core::option::Option::Some( ::core::convert::Into::into( src ) ); - self - }} -}} - - "#, - former, - former_storage, - field_ident, - format!( "{}", qt!{ #typ } ), - field_ident, - field_ident, - ); - println!( "{hint}" ); - } - - if !self.scalar_setter_required() - { - return qt! {}; - } - - let doc = format! - ( - "Scalar setter for the '{}' field.", - field_ident, - ); - - qt! - { - #[ doc = #doc ] - #[ inline ] - pub fn #setter_name< Src >( mut self, src : Src ) -> Self - where - Src : ::core::convert::Into< #typ >, - { - debug_assert!( self.storage.#field_ident.is_none() ); - self.storage.#field_ident = ::core::option::Option::Some( ::core::convert::Into::into( src ) ); - self - } - } - } - /// Get name of scalar setter. pub fn scalar_setter_name( &self ) -> &syn::Ident { @@ -1105,11 +1459,10 @@ where return &self.ident; } - /// Get name of setter for container if such setter should be generated. - pub fn container_setter_name( &self ) -> Option< &syn::Ident > + /// Get name of setter for subform scalar if such setter should be generated. + pub fn subform_scalar_setter_name( &self ) -> Option< &syn::Ident > { - - if let Some( ref attr ) = self.attrs.container + if let Some( ref attr ) = self.attrs.subform_scalar { if attr.setter() { @@ -1123,15 +1476,33 @@ where } } } + return None; + } + /// Get name of setter for collection if such setter should be generated. + pub fn subform_collection_setter_name( &self ) -> Option< &syn::Ident > + { + if let Some( ref attr ) = self.attrs.subform_collection + { + if attr.setter() + { + if let Some( ref name ) = attr.name + { + return Some( &name ) + } + else + { + return Some( &self.ident ) + } + } + } return None; } /// Get name of setter for subform if such setter should be generated. - pub fn subform_setter_name( &self ) -> Option< &syn::Ident > + pub fn subform_entry_setter_name( &self ) -> Option< &syn::Ident > { - - if let Some( ref attr ) = self.attrs.subform + if let Some( ref attr ) = self.attrs.subform_entry { if attr.setter() { @@ -1145,11 +1516,10 @@ where } } } - return None; } - /// Is scalar setter required. Does not if container of subformer setter requested. + /// Is scalar setter required. Does not if collection of subformer setter requested. pub fn scalar_setter_required( &self ) -> bool { @@ -1170,12 +1540,17 @@ where } } - if self.attrs.container.is_some() && !explicit + if self.attrs.subform_scalar.is_some() && !explicit + { + return false; + } + + if self.attrs.subform_collection.is_some() && !explicit { return false; } - if self.attrs.subform.is_some() && !explicit + if self.attrs.subform_entry.is_some() && !explicit { return false; } 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 5aea94b80d..137f84249e 100644 --- a/module/core/former_meta/src/derive_former/field_attrs.rs +++ b/module/core/former_meta/src/derive_former/field_attrs.rs @@ -10,8 +10,9 @@ pub struct FieldAttributes { pub config : Option< AttributeConfig >, pub scalar : Option< AttributeScalarSetter >, - pub container : Option< AttributeContainerSetter >, - pub subform : Option< AttributeSubformSetter >, + pub subform_scalar : Option< AttributeSubformScalarSetter >, + pub subform_collection : Option< AttributeSubformCollectionSetter >, + pub subform_entry : Option< AttributeSubformEntrySetter >, } impl FieldAttributes @@ -21,8 +22,9 @@ impl FieldAttributes { let mut config = None; let mut scalar = None; - let mut container = None; - let mut subform = None; + let mut subform_scalar = None; + let mut subform_collection = None; + let mut subform_entry = None; for attr in attrs { let key_ident = attr.path().get_ident() @@ -53,6 +55,7 @@ impl FieldAttributes } "scalar" => { + // qqq : move this part of parsing into attribute. do that for all attributes match attr.meta { syn::Meta::List( ref meta_list ) => @@ -63,37 +66,52 @@ impl FieldAttributes { scalar.replace( syn::parse2::< AttributeScalarSetter >( Default::default() )? ); }, - _ => return_syn_err!( attr, "Expects an attribute of format `#[ scalar( setter = false ) ]` or `#[ scalar( setter = false, name = my_name ) ]`. \nGot: {}", qt!{ #attr } ), + _ => return_syn_err!( attr, "Expects an attribute of format `#[ scalar( setter = false ) ]` or `#[ scalar( setter = true, name = my_name ) ]`. \nGot: {}", qt!{ #attr } ), } } - "container" => + "subform_scalar" => { match attr.meta { syn::Meta::List( ref meta_list ) => { - container.replace( syn::parse2::< AttributeContainerSetter >( meta_list.tokens.clone() )? ); + subform_scalar.replace( syn::parse2::< AttributeSubformScalarSetter >( meta_list.tokens.clone() )? ); }, syn::Meta::Path( ref _path ) => { - container.replace( syn::parse2::< AttributeContainerSetter >( Default::default() )? ); + subform_scalar.replace( syn::parse2::< AttributeSubformScalarSetter >( Default::default() )? ); }, - _ => return_syn_err!( attr, "Expects an attribute of format `#[ container ]` or `#[ container( definition = former::VectorDefinition ) ]` if you want to use default container defition. \nGot: {}", qt!{ #attr } ), + _ => return_syn_err!( attr, "Expects an attribute of format `#[ subform_scalar( setter = false ) ]` or `#[ subform_scalar( setter = true, name = my_name ) ]`. \nGot: {}", qt!{ #attr } ), } } - "subform" => + "subform_collection" => { match attr.meta { syn::Meta::List( ref meta_list ) => { - subform.replace( syn::parse2::< AttributeSubformSetter >( meta_list.tokens.clone() )? ); + subform_collection.replace( syn::parse2::< AttributeSubformCollectionSetter >( meta_list.tokens.clone() )? ); }, syn::Meta::Path( ref _path ) => { - subform.replace( syn::parse2::< AttributeSubformSetter >( Default::default() )? ); + subform_collection.replace( syn::parse2::< AttributeSubformCollectionSetter >( Default::default() )? ); }, - _ => return_syn_err!( attr, "Expects an attribute of format `#[ subform ]` or `#[ subform( name : child )` ], \nGot: {}", qt!{ #attr } ), + _ => return_syn_err!( attr, "Expects an attribute of format `#[ subform_collection ]` or `#[ subform_collection( definition = former::VectorDefinition ) ]` if you want to use default collection defition. \nGot: {}", qt!{ #attr } ), + } + } + "subform_entry" => + { + match attr.meta + { + syn::Meta::List( ref meta_list ) => + { + subform_entry.replace( syn::parse2::< AttributeSubformEntrySetter >( meta_list.tokens.clone() )? ); + }, + syn::Meta::Path( ref _path ) => + { + subform_entry.replace( syn::parse2::< AttributeSubformEntrySetter >( Default::default() )? ); + }, + _ => return_syn_err!( attr, "Expects an attribute of format `#[ subform_entry ]` or `#[ subform_entry( name : child )` ], \nGot: {}", qt!{ #attr } ), } } _ => @@ -103,7 +121,7 @@ impl FieldAttributes } } - Ok( FieldAttributes { config, scalar, container, subform } ) + Ok( FieldAttributes { config, scalar, subform_scalar, subform_collection, subform_entry } ) } } @@ -252,10 +270,97 @@ impl syn::parse::Parse for AttributeScalarSetter } } -/// Represents an attribute for configuring container setter generation. +/// +/// Attribute to enable/disable scalar setter generation. +/// +/// ## Example Input +/// +/// A typical input to parse might look like the following: +/// +/// ```ignore +/// name = field_name, setter = true +/// ``` +/// + +pub struct AttributeSubformScalarSetter +{ + /// Optional identifier for naming the setter. + pub name : Option< syn::Ident >, + /// Controls the generation of a setter method. If false, a setter method is not generated. + pub setter : Option< bool >, + /// 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 : bool, +} + +#[ allow( dead_code ) ] +impl AttributeSubformScalarSetter +{ + + /// Should setter be generated or not? + pub fn setter( &self ) -> bool + { + self.setter.is_none() || self.setter.unwrap() + } + +} + +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()?; + if ident == "name" + { + input.parse::< syn::Token![ = ] >()?; + name = Some( input.parse()? ); + } + else if ident == "setter" + { + input.parse::< syn::Token![ = ] >()?; + let value : syn::LitBool = input.parse()?; + setter = Some( value.value() ); + } + else if ident == "hint" + { + input.parse::< syn::Token![ = ] >()?; + let value : syn::LitBool = input.parse()?; + hint = value.value; + } + else + { + 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, setter, hint } ) + } +} + +/// 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. -/// It allows the customization of setter methods and the specification of the container's behavior through meta attributes. +/// It allows the customization of setter methods and the specification of the collection's behavior through meta attributes. /// /// ## Example Input /// @@ -265,20 +370,20 @@ impl syn::parse::Parse for AttributeScalarSetter /// ``` /// -pub struct AttributeContainerSetter +pub struct AttributeSubformCollectionSetter { /// Optional identifier for naming the setter. pub name : Option< syn::Ident >, /// Controls the generation of a setter method. If false, a setter method is not generated. pub setter : Option< bool >, - /// Definition of the container former to use, e.g., `former::VectorFormer`. + /// Definition of the collection former to use, e.g., `former::VectorFormer`. pub definition : Option< syn::Type >, /// 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 : bool, } -impl AttributeContainerSetter +impl AttributeSubformCollectionSetter { /// Should setter be generated or not? @@ -289,7 +394,7 @@ impl AttributeContainerSetter } -impl syn::parse::Parse for AttributeContainerSetter +impl syn::parse::Parse for AttributeSubformCollectionSetter { fn parse( input : syn::parse::ParseStream< '_ > ) -> syn::Result< Self > { @@ -328,12 +433,12 @@ impl syn::parse::Parse for AttributeContainerSetter } else { - return Err( syn::Error::new_spanned( &ident, format!( "Unexpected identifier '{}'. Expected 'name', 'setter', or 'definition'. For example: `container( name = myName, setter = true, definition = MyDefinition )`", ident ) ) ); + return Err( syn::Error::new_spanned( &ident, format!( "Unexpected identifier '{}'. Expected 'name', 'setter', or 'definition'. For example: `collection( name = myName, setter = true, definition = MyDefinition )`", ident ) ) ); } } else { - return Err( syn::Error::new( input.span(), "Expected 'name', 'setter', or 'definition' identifier. For example: `container( name = myName, setter = true, definition = MyDefinition )`" ) ); + return Err( syn::Error::new( input.span(), "Expected 'name', 'setter', or 'definition' identifier. For example: `collection( name = myName, setter = true, definition = MyDefinition )`" ) ); } // Optional comma handling @@ -365,20 +470,20 @@ impl syn::parse::Parse for AttributeContainerSetter /// mame = field_name /// ``` -pub struct AttributeSubformSetter +pub struct AttributeSubformEntrySetter { /// An optional identifier that names the setter. It is parsed from inputs /// like `name = my_field`. pub name : Option< syn::Ident >, /// Disable generation of setter. - /// It still generate `_field_add` method, so it could be used to make a setter with custom arguments. + /// It still generate `_field_subform_entry` method, so it could be used to make a setter with custom arguments. pub setter : Option< bool >, /// 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 : bool, } -impl AttributeSubformSetter +impl AttributeSubformEntrySetter { /// Should setter be generated or not? @@ -389,7 +494,7 @@ impl AttributeSubformSetter } -impl syn::parse::Parse for AttributeSubformSetter +impl syn::parse::Parse for AttributeSubformEntrySetter { fn parse( input : syn::parse::ParseStream< '_ > ) -> syn::Result< Self > { diff --git a/module/core/former_meta/src/lib.rs b/module/core/former_meta/src/lib.rs index cf131eef6f..f8fbcaef86 100644 --- a/module/core/former_meta/src/lib.rs +++ b/module/core/former_meta/src/lib.rs @@ -48,7 +48,7 @@ mod derive_former; /// /// - `former`: General attribute to specify various options like defaults or inclusion in the former. /// - `scalar`: Indicates that the field is a scalar value, enabling direct assignment without the need for a sub-former. -/// - `container`: Marks the field as a container that can use specific former methods to manage its contents. +/// - `collection`: Marks the field as a collection that can use specific former methods to manage its contents. /// - `subform`: Specifies that the field should utilize a nested former, facilitating the construction of complex nested structures. /// /// # Usage Example @@ -102,7 +102,7 @@ mod derive_former; attributes ( debug, perform, storage_fields, mutator, // struct attributes - former, scalar, container, subform, // field attributes + former, scalar, subform_scalar, subform_collection, subform_entry, // field attributes ) ) ] diff --git a/module/core/interval_adapter/Cargo.toml b/module/core/interval_adapter/Cargo.toml index 218f3b9d96..e02a0aeae2 100644 --- a/module/core/interval_adapter/Cargo.toml +++ b/module/core/interval_adapter/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "interval_adapter" -version = "0.19.0" +version = "0.20.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", diff --git a/module/core/process_tools/Cargo.toml b/module/core/process_tools/Cargo.toml index 7f31dceaa1..f28259801b 100644 --- a/module/core/process_tools/Cargo.toml +++ b/module/core/process_tools/Cargo.toml @@ -28,22 +28,6 @@ all-features = false [features] default = [ "enabled", "process_environment_is_cicd" ] full = [ "enabled", "process_environment_is_cicd" ] -no_std = [ - "former/no_std", - # xxx - # "proper_path_tools/no_std", - # "error_tools/no_std", - # "iter_tools/no_std", - "test_tools/no_std", -] -use_alloc = [ - "no_std", - "former/use_alloc", - # "proper_path_tools/use_alloc", - # "error_tools/use_alloc", - # "iter_tools/use_alloc", - "test_tools/use_alloc", -] enabled = [ "mod_interface/enabled", "former/enabled", diff --git a/module/core/process_tools/src/process.rs b/module/core/process_tools/src/process.rs index eac9643740..db954da17c 100644 --- a/module/core/process_tools/src/process.rs +++ b/module/core/process_tools/src/process.rs @@ -298,6 +298,7 @@ pub( crate ) mod private } } } + impl core::fmt::Display for Report { fn fmt( &self, f : &mut Formatter< '_ > ) -> core::fmt::Result diff --git a/module/core/program_tools/Cargo.toml b/module/core/program_tools/Cargo.toml new file mode 100644 index 0000000000..30faf2edc3 --- /dev/null +++ b/module/core/program_tools/Cargo.toml @@ -0,0 +1,57 @@ +[package] +name = "program_tools" +version = "0.1.0" +edition = "2021" +authors = [ + "Kostiantyn Wandalen ", +] +license = "MIT" +readme = "Readme.md" +documentation = "https://docs.rs/program_tools" +repository = "https://github.com/Wandalen/wTools/tree/master/module/core/program_tools" +homepage = "https://github.com/Wandalen/wTools/tree/master/module/core/program_tools" +description = """ +Compile and run a Rust program. +""" +categories = [ "algorithms", "development-tools" ] +keywords = [ "fundamental", "general-purpose" ] + +[lints] +workspace = true + + +[package.metadata.docs.rs] +features = [ "full" ] +all-features = false + + +[features] +default = [ + "enabled", +] +full = [ + "enabled" + ] + +enabled = [ + "mod_interface/enabled", + "former/enabled", + "proper_path_tools/enabled", + "error_tools/enabled", + "iter_tools/enabled", +] + +[dependencies] +mod_interface = { workspace = true } +former = { workspace = true, features = [ "derive_former" ] } +proper_path_tools = { workspace = true } +error_tools = { workspace = true, features = [ "error_for_app" ] } # qqq : xxx : rid off error_for_app +iter_tools = { workspace = true } + +# ## external +# duct = "0.13.7" + + +[dev-dependencies] +test_tools = { workspace = true } +# assert_fs = { version = "1.1.1" } diff --git a/module/core/program_tools/License b/module/core/program_tools/License new file mode 100644 index 0000000000..6d5ef8559f --- /dev/null +++ b/module/core/program_tools/License @@ -0,0 +1,22 @@ +Copyright Kostiantyn W and Out of the Box Systems (c) 2013-2024 + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/module/core/program_tools/Readme.md b/module/core/program_tools/Readme.md new file mode 100644 index 0000000000..daf1b1c108 --- /dev/null +++ b/module/core/program_tools/Readme.md @@ -0,0 +1,33 @@ + + +# Module :: program_tools + + [![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) [![rust-status](https://github.com/Wandalen/wTools/actions/workflows/module_program_tools_push.yml/badge.svg)](https://github.com/Wandalen/wTools/actions/workflows/module_program_tools_push.yml) [![docs.rs](https://img.shields.io/docsrs/program_tools?color=e3e8f0&logo=docs.rs)](https://docs.rs/program_tools) [![discord](https://img.shields.io/discord/872391416519737405?color=eee&logo=discord&logoColor=eee&label=ask)](https://discord.gg/m3YfbXpUUY) + + +Compile and run a Rust program. + + diff --git a/module/core/program_tools/src/lib.rs b/module/core/program_tools/src/lib.rs new file mode 100644 index 0000000000..ced6f3d8d8 --- /dev/null +++ b/module/core/program_tools/src/lib.rs @@ -0,0 +1,19 @@ +// #![ cfg_attr( feature = "no_std", no_std ) ] +#![ doc( html_logo_url = "https://raw.githubusercontent.com/Wandalen/wTools/master/asset/img/logo_v3_trans_square.png" ) ] +#![ doc( html_favicon_url = "https://raw.githubusercontent.com/Wandalen/wTools/alpha/asset/img/logo_v3_trans_square_icon_small_v2.ico" ) ] +#![ doc( html_root_url = "https://docs.rs/program_tools/latest/program_tools/" ) ] +#![ doc = include_str!( concat!( env!( "CARGO_MANIFEST_DIR" ), "/", "Readme.md" ) ) ] + +#![ allow( unused_imports, dead_code ) ] // xxx : rid off + +#[ cfg( feature = "enabled" ) ] +use mod_interface::mod_interface; + +#[ cfg( feature = "enabled" ) ] +mod_interface! +{ + + /// Compile and run a Rust program. + layer program; + +} diff --git a/module/core/program_tools/src/program.rs b/module/core/program_tools/src/program.rs new file mode 100644 index 0000000000..adf0201ad3 --- /dev/null +++ b/module/core/program_tools/src/program.rs @@ -0,0 +1,103 @@ +/// Internal namespace. +pub( crate ) mod private +{ + + use former::Former; + use std:: + { + path::{ Path, PathBuf }, + // process::Command, + }; + + #[ derive( Debug, Default, Former ) ] + pub struct SourceFile + { + file_path : PathBuf, + data : GetData, + } + + #[ derive( Debug, Default, Former ) ] + pub struct Entry + { + source_file : SourceFile, + typ : EntryType, + } + + #[ derive( Debug, Default, Former ) ] + pub struct CargoFile + { + file_path : PathBuf, + data : GetData, + } + + #[ derive( Debug, Default, Former ) ] + // #[ debug ] + pub struct Program + { + write_path : Option< PathBuf >, + read_path : Option< PathBuf >, + #[ subform_entry( name = entry ) ] + entries : Vec< Entry >, + #[ subform_entry( name = source ) ] + sources : Vec< SourceFile >, + cargo_file : Option< CargoFile >, + } + + #[ derive( Debug, Default, Former ) ] + pub struct ProgramPlan + { + // #[ embed ] + program : Program, + calls : Vec< ProgramCall >, + } + + #[ derive( Debug ) ] + pub enum GetData + { + FromStr( &'static str ), + FromBin( &'static [ u8 ] ), + FromFile( PathBuf ), + FromString( String ), + } + + impl Default for GetData + { + fn default() -> Self + { + GetData::FromStr( "" ) + } + } + + #[ derive( Debug, Default ) ] + pub struct ProgramCall + { + action : ProgramAction, + current_path : Option< PathBuf >, + args : Vec< String >, + index_of_entry : i32, + } + + #[ derive( Debug, Default ) ] + pub enum ProgramAction + { + #[ default ] + Run, + Build, + Test, + } + + #[ derive( Debug, Default ) ] + pub enum EntryType + { + #[ default ] + Bin, + Lib, + Test, + } + +} + +crate::mod_interface! +{ + // protected use run; +} diff --git a/module/core/program_tools/tests/asset/err_out_test/err_out_err.rs b/module/core/program_tools/tests/asset/err_out_test/err_out_err.rs new file mode 100644 index 0000000000..d6bc10ff45 --- /dev/null +++ b/module/core/program_tools/tests/asset/err_out_test/err_out_err.rs @@ -0,0 +1,8 @@ +fn main() +{ + eprintln!( "This is stderr text" ); + + println!( "This is stdout text" ); + + eprintln!( "This is stderr text" ); +} diff --git a/module/core/program_tools/tests/asset/err_out_test/out_err_out.rs b/module/core/program_tools/tests/asset/err_out_test/out_err_out.rs new file mode 100644 index 0000000000..eeb47d28bf --- /dev/null +++ b/module/core/program_tools/tests/asset/err_out_test/out_err_out.rs @@ -0,0 +1,9 @@ +//! need for tests +fn main() +{ + println!( "This is stdout text" ); + + eprintln!( "This is stderr text" ); + + println!( "This is stdout text" ); +} diff --git a/module/core/program_tools/tests/inc/basic.rs b/module/core/program_tools/tests/inc/basic.rs new file mode 100644 index 0000000000..60c9a81cfb --- /dev/null +++ b/module/core/program_tools/tests/inc/basic.rs @@ -0,0 +1,7 @@ +#[ allow( unused_imports ) ] +use super::*; + +#[ test ] +fn basic() +{ +} diff --git a/module/core/program_tools/tests/inc/mod.rs b/module/core/program_tools/tests/inc/mod.rs new file mode 100644 index 0000000000..d78794e341 --- /dev/null +++ b/module/core/program_tools/tests/inc/mod.rs @@ -0,0 +1,4 @@ +#[ allow( unused_imports ) ] +use super::*; + +mod basic; diff --git a/module/core/program_tools/tests/smoke_test.rs b/module/core/program_tools/tests/smoke_test.rs new file mode 100644 index 0000000000..7fd288e61d --- /dev/null +++ b/module/core/program_tools/tests/smoke_test.rs @@ -0,0 +1,14 @@ + +// #[ cfg( feature = "default" ) ] +#[ test ] +fn local_smoke_test() +{ + ::test_tools::smoke_test_for_local_run(); +} + +// #[ cfg( feature = "default" ) ] +#[ test ] +fn published_smoke_test() +{ + ::test_tools::smoke_test_for_published_run(); +} diff --git a/module/core/program_tools/tests/tests.rs b/module/core/program_tools/tests/tests.rs new file mode 100644 index 0000000000..e353b1d4d9 --- /dev/null +++ b/module/core/program_tools/tests/tests.rs @@ -0,0 +1,11 @@ + +include!( "../../../../module/step/meta/src/module/terminal.rs" ); + +#[ allow( unused_imports ) ] +use program_tools as the_module; + +#[ allow( unused_imports ) ] +use test_tools::exposed::*; + +#[ cfg( feature = "enabled" ) ] +mod inc; diff --git a/module/core/program_tools/tests/tool/asset.rs b/module/core/program_tools/tests/tool/asset.rs new file mode 100644 index 0000000000..7261904225 --- /dev/null +++ b/module/core/program_tools/tests/tool/asset.rs @@ -0,0 +1,140 @@ + +// xxx2 : incorporate the function into a tool + +pub const ASSET_PATH : &str = "tests/asset"; + +macro_rules! ERR_MSG +{ + () + => + { + "Create `.cargo/config.toml` file at root of your project and append it by +``` +[env] +WORKSPACE_PATH = { value = \".\", relative = true } +```" + }; +} + +pub fn path() -> std::io::Result< std::path::PathBuf > +{ + use std:: + { + path::Path, + io::{ self, ErrorKind } + }; + let workspace_path = Path::new( env!( "WORKSPACE_PATH", ERR_MSG!{} ) ); + // dbg!( workspace_path ); + // let crate_path = Path::new( env!( "CARGO_MANIFEST_DIR" ) ); + // dbg!( file!() ); + let dir_path = workspace_path.join( Path::new( file!() ) ); + let dir_path = dir_path.canonicalize()?; + let test_dir = dir_path + .parent() + .ok_or_else( || io::Error::new( ErrorKind::NotFound, format!( "Failed to find parent directory {}", dir_path.display() ) ) )? + .parent() + .ok_or_else( || io::Error::new( ErrorKind::NotFound, format!( "Failed to find parent directory {}", dir_path.display() ) ) )? + .parent() + .ok_or_else( || io::Error::new( ErrorKind::NotFound, format!( "Failed to find parent directory {}", dir_path.display() ) ) )? + ; + // dbg!( &test_dir ); + let assets_path = test_dir.join( Path::new( ASSET_PATH ) ); + // dbg!( &assets_path ); + Ok( assets_path ) +} + +// + +// xxx2 : adjust Former to generate required code easier +// xxx2 : implement the interface + +use former::Former; +use std:: +{ + path::{ Path, PathBuf }, + // process::Command, +}; + +#[ derive( Debug, Default, Former ) ] +pub struct SourceFile +{ + file_path : PathBuf, + data : GetData, +} + +#[ derive( Debug, Default, Former ) ] +pub struct Entry +{ + source_file : SourceFile, + typ : EntryType, +} + +#[ derive( Debug, Default, Former ) ] +pub struct CargoFile +{ + file_path : PathBuf, + data : GetData, +} + +#[ derive( Debug, Default, Former ) ] +// #[ debug ] +pub struct Program +{ + write_path : Option< PathBuf >, + read_path : Option< PathBuf >, + entries : Vec< Entry >, + sources : Vec< SourceFile >, + cargo_file : Option< CargoFile >, +} + +#[ derive( Debug, Default, Former ) ] +pub struct ProgramRun +{ + // #[ embed ] + program : Program, + calls : Vec< ProgramCall >, +} + +#[ derive( Debug ) ] +pub enum GetData +{ + FromStr( &'static str ), + FromBin( &'static [ u8 ] ), + FromFile( PathBuf ), + FromString( String ), +} + +impl Default for GetData +{ + fn default() -> Self + { + GetData::FromStr( "" ) + } +} + +#[ derive( Debug, Default ) ] +pub struct ProgramCall +{ + action : ProgramAction, + current_path : Option< PathBuf >, + args : Vec< String >, + index_of_entry : i32, +} + +#[ derive( Debug, Default ) ] +pub enum ProgramAction +{ + #[ default ] + Run, + Build, + Test, +} + +#[ derive( Debug, Default ) ] +pub enum EntryType +{ + #[ default ] + Bin, + Lib, + Test, +} diff --git a/module/move/crates_tools/src/lib.rs b/module/move/crates_tools/src/lib.rs index 569549e54f..20a89cd7cf 100644 --- a/module/move/crates_tools/src/lib.rs +++ b/module/move/crates_tools/src/lib.rs @@ -1,13 +1,8 @@ #![ doc( html_logo_url = "https://raw.githubusercontent.com/Wandalen/wTools/master/asset/img/logo_v3_trans_square.png" ) ] #![ doc( html_favicon_url = "https://raw.githubusercontent.com/Wandalen/wTools/alpha/asset/img/logo_v3_trans_square_icon_small_v2.ico" ) ] #![ doc( html_root_url = "https://docs.rs/crates_tools/latest/crates_tools/" ) ] - #![ doc = include_str!( concat!( env!( "CARGO_MANIFEST_DIR" ), "/", "Readme.md" ) ) ] -//! -//! Tools to analyse crate files. -//! - /// Internal namespace. #[ cfg( feature = "enabled" ) ] pub( crate ) mod private diff --git a/module/move/wca/src/ca/grammar/command.rs b/module/move/wca/src/ca/grammar/command.rs index 2f12e03921..a582aeee91 100644 --- a/module/move/wca/src/ca/grammar/command.rs +++ b/module/move/wca/src/ca/grammar/command.rs @@ -96,7 +96,7 @@ pub( crate ) mod private /// Phrase descriptor for command. pub phrase : String, /// Command subjects hints and types. - #[ subform( setter = true ) ] + #[ subform_entry( setter = true ) ] pub subjects : Vec< ValueDescription >, /// Hints and types for command options. pub properties : HashMap< String, ValueDescription >, @@ -179,7 +179,7 @@ pub( crate ) mod private /// It returns a `ValueDescriptionFormer` which can be used to further build the super-former. pub fn subject( self ) -> ValueDescriptionAsSubformer< Self, impl ValueDescriptionAsSubformerEnd< Self > > { - self._subjects_add() + self._subjects_subform_entry() } /// Sets the name and other properties of the current property. diff --git a/module/move/willbe/src/tool/template.rs b/module/move/willbe/src/tool/template.rs index 044f1157b9..44f0e4bb9e 100644 --- a/module/move/willbe/src/tool/template.rs +++ b/module/move/willbe/src/tool/template.rs @@ -107,7 +107,7 @@ mod private #[ derive( Debug, Default, Former ) ] pub struct TemplateParameters { - #[ subform( setter = false ) ] + #[ subform_entry( setter = false ) ] descriptors : Vec< TemplateParameterDescriptor > } @@ -147,7 +147,7 @@ mod private pub fn parameter( self, name : &str ) -> TemplateParameterDescriptorAsSubformer< Self, impl TemplateParameterDescriptorAsSubformerEnd< Self > > { - self._descriptors_add::< TemplateParameterDescriptorFormer< _ >, _ >() + self._descriptors_subform_entry::< TemplateParameterDescriptorFormer< _ >, _ >() .parameter( name ) } } @@ -302,7 +302,7 @@ mod private pub struct TemplateFilesBuilder { /// Stores all file descriptors for current template. - #[ subform( setter = true ) ] + #[ subform_entry( setter = true ) ] #[ scalar( setter = false, hint = false ) ] pub files : Vec< TemplateFileDescriptor >, } @@ -314,7 +314,7 @@ mod private #[ inline( always ) ] pub fn file( self ) -> TemplateFileDescriptorAsSubformer< Self, impl TemplateFileDescriptorAsSubformerEnd< Self > > { - self._files_add() + self._files_subform_entry() } }