You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[](https://github.com/emersion/stability-badges#experimental)[](https://github.com/Wandalen/wTools/actions/workflows/module_component_model_push.yml)[](https://docs.rs/component_model)[](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=module%2Fcore%2Fcomponent_model%2Fexamples%2Fcomponent_model_trivial.rs,RUN_POSTFIX=--example%20module%2Fcore%2Fcomponent_model%2Fexamples%2Fcomponent_model_trivial.rs/https://github.com/Wandalen/wTools)[](https://discord.gg/m3YfbXpUUY)
6
-
<!--{ generate.module_header.end }-->
7
4
8
-
A flexible implementation of the Builder pattern supporting nested builders and collection-specific subcomponent_models.
[](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=module%2Fcore%2Fcomponent_model%2Fexamples%2Fcomponent_model_trivial.rs,RUN_POSTFIX=--example%20module%2Fcore%2Fcomponent_model%2Fexamples%2Fcomponent_model_trivial.rs/https://github.com/Wandalen/wTools)
The `component_model` crate provides a powerful derive macro, `#[ derive( Former ) ]`, that automatically implements the **Builder pattern** for your Rust structs and enums.
13
-
14
-
Its primary goal is to **simplify the construction of complex objects**, especially those with numerous fields, optional values, default settings, collections, or nested structures, making your initialization code more readable and maintainable.
15
-
16
-
## Why Use `Former`?
17
-
18
-
Compared to manually implementing the Builder pattern or using other builder crates, `component_model` offers several advantages:
19
-
20
-
***Reduced Boilerplate:**`#[ derive( Former ) ]` automatically generates the builder struct, storage, and setters, saving you significant repetitive coding effort.
21
-
***Fluent & Readable API:** Construct objects step-by-step using clear, chainable methods (`.field_name( value )`).
22
-
***Effortless Defaults & Optionals:** Fields automatically use their `Default` implementation if not set. `Option< T >` fields are handled seamlessly – you only set them if you have a `Some( value )`. Custom defaults can be specified easily with `#[ component_model( default = ... ) ]`.
23
-
***Powerful Collection & Nested Struct Handling:**`component_model` truly shines with its **subcomponent_model** system. Easily build `Vec`, `HashMap`, `HashSet`, and other collections element-by-element, or configure nested structs using their own dedicated component_models within the parent's builder chain. This is often more complex to achieve with other solutions.
11
+
A flexible component model for Rust supporting generic assignment and type-based field access.
24
12
25
13
## Installation
26
14
@@ -30,300 +18,53 @@ Add `component_model` to your `Cargo.toml`:
30
18
cargo add component_model
31
19
```
32
20
33
-
The default features enable the `Former` derive macro and support for standard collections, covering most common use cases.
34
-
35
-
## Basic Usage
36
-
37
-
Derive `Former` on your struct and use the generated `::component_model()` method to start building:
[Run this example locally](https://github.com/Wandalen/wTools/blob/master/module/core/component_model/examples/component_model_trivial.rs) | [Try it online](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=module%2Fcore%2Fcomponent_model%2Fexamples%2Fcomponent_model_trivial.rs,RUN_POSTFIX=--example%20module%2Fcore%2Fcomponent_model%2Fexamples%2Fcomponent_model_trivial.rs/https://github.com/Wandalen/wTools)
99
-
100
-
## Handling Optionals and Defaults
101
-
102
-
`Former` makes working with optional fields and default values straightforward:
103
-
104
-
***`Option< T >` Fields:** As seen in the basic example, fields of type `Option< T >` automatically default to `None`. You only need to call the setter if you have a `Some( value )`.
105
-
106
-
***Custom Defaults:** For required fields that don't implement `Default`, or when you need a specific default value other than the type's default, use the `#[ component_model( default = ... ) ]` attribute:
assert_eq!(person, Person { age:42, name:"Alice".to_string() });
55
+
}
146
56
```
147
-
[See full example code](https://github.com/Wandalen/wTools/blob/master/module/core/component_model/examples/component_model_custom_defaults.rs)
148
-
149
-
## Building Collections & Nested Structs (Subcomponent_models)
150
-
151
-
Where `component_model` significantly simplifies complex scenarios is in building collections (`Vec`, `HashMap`, etc.) or nested structs. It achieves this through **subcomponent_models**. Instead of setting the entire collection/struct at once, you get a dedicated builder for the field:
`component_model` provides different subform attributes (`#[ subform_collection ]`, `#[ subform_entry ]`, `#[ subform_scalar ]`) for various collection and nesting patterns.
194
-
195
-
## Standalone Constructors
196
-
197
-
For scenarios where you want a direct constructor function instead of always starting with `YourType::component_model()`, `component_model` offers standalone constructors.
198
-
199
-
***Enable:** Add `#[ standalone_constructors ]` to your struct or enum definition.
200
-
***Function Name:** A function named after your type (in snake_case) will be generated (e.g., `my_struct()` for `struct MyStruct`). For enums, functions are named after variants (e.g., `my_variant()` for `enum E { MyVariant }`).
201
-
***Arguments:** By default, the constructor takes no arguments and returns the `Former` type.
202
-
***Specify Arguments:** Mark specific fields with `#[ arg_for_constructor ]` to make them required arguments for the standalone constructor.
203
-
***Return Type (Option 2 Logic):**
204
-
* If **all** fields of the struct/variant are marked with `#[ arg_for_constructor ]`, the standalone constructor returns the instance directly (`Self`).
205
-
* If **zero or some** fields are marked, the standalone constructor returns the `Former` type, pre-initialized with the provided arguments.
***Component Model:** Separate derives (`Assign`, `ComponentFrom`, `ComponentsAssign`, `FromComponents`) for type-based field access and conversion (See `component_model_types` documentation).
64
+
See [component_model_types documentation](https://docs.rs/component_model_types) for details.
323
65
324
66
## Where to Go Next
325
67
326
-
***[Advanced Usage & Concepts](https://github.com/Wandalen/wTools/tree/master/module/core/component_model/advanced.md):** Dive deeper into subcomponent_models, customization options, storage, context, definitions, mutators, and custom collections.
327
-
***[Examples Directory](https://github.com/Wandalen/wTools/tree/master/module/core/component_model/examples):** Explore practical, runnable examples showcasing various features.
328
-
***[API Documentation (docs.rs)](https://docs.rs/component_model):** Get detailed information on all public types, traits, and functions.
329
-
***[Repository (GitHub)](https://github.com/Wandalen/wTools/tree/master/module/core/component_model):** View the source code, contribute, or report issues.
-[API Documentation (docs.rs)](https://docs.rs/component_model): Get detailed information on all public types, traits, and functions.
70
+
-[Repository (GitHub)](https://github.com/Wandalen/wTools/tree/master/module/core/component_model): View the source code, contribute, or report issues.
0 commit comments