former_types/forming.rs
1//! Module `forming`
2//!
3//! This module defines a collection of traits that are crucial for implementing a structured and extensible builder pattern.
4//! The traits provided manage the various stages of the forming process, handling the initiation, mutation, and completion
5//! of constructing complex data structures. These traits facilitate the creation of flexible and maintainable formation
6//! logic that can accommodate complex construction scenarios, including nested and conditional formations.
7
8/// Provides a mechanism for mutating the context and storage just before the forming process is completed.
9///
10/// The `FormerMutator` trait allows for the implementation of custom mutation logic on the internal state
11/// of an entity (context and storage) just before the final forming operation is completed. This mutation
12/// occurs immediately before the `FormingEnd` callback is invoked.
13///
14/// #### Differences from `FormingEnd`
15///
16/// Unlike `FormingEnd`, which is responsible for integrating and finalizing the formation process of a field within
17/// a parent former, `form_mutation` directly pertains to the entity itself. This method is designed to be independent
18/// of whether the forming process is occurring within the context of a superformer or if the structure is a standalone
19/// or nested field. This makes `form_mutation` suitable for entity-specific transformations that should not interfere
20/// with the hierarchical forming logic managed by `FormingEnd`.
21///
22/// #### Use Cases
23///
24/// - Applying last-minute changes to the data being formed.
25/// - Setting or modifying properties that depend on the final state of the storage or context.
26/// - Storage-specific fields which are not present in formed structure.
27///
28/// Look example `former_custom_mutator.rs`
29pub trait FormerMutator
30where
31 Self: crate::FormerDefinitionTypes,
32{
33 /// Mutates the context and storage of the entity just before the formation process completes.
34 ///
35 /// This function is invoked immediately prior to the `FormingEnd` callback during the forming process.
36 /// It provides a hook for implementing custom logic that modifies the internal state (storage and context)
37 /// of the entity. `form_mutation` is particularly useful for adjustments or updates that need to reflect
38 /// in the entity just before it is finalized and returned.
39 ///
40 #[ inline ]
41 fn form_mutation( _storage : &mut Self::Storage, _context : &mut ::core::option::Option< Self::Context > ) {}
42}
43
44// impl< Definition > crate::FormerMutator
45// for Definition
46// where
47// Definition : crate::FormerDefinitionTypes,
48// {
49// }
50
51/// Defines a handler for the end of a subforming process, enabling the return of the original context.
52///
53/// This trait is designed to be flexible, allowing for various end-of-forming behaviors in builder patterns.
54/// Implementors can define how to transform or pass through the context during the forming process's completion.
55///
56/// # Parameters
57/// - `Storage`: The type of the collection being processed.
58/// - `Context`: The type of the context that might be altered or returned upon completion.
59pub trait FormingEnd< Definition : crate::FormerDefinitionTypes >
60{
61 /// Called at the end of the subforming process to return the modified or original context.
62 ///
63 /// # Parameters
64 /// - `collection`: The collection being processed.
65 /// - `context`: Optional context to be transformed or returned.
66 ///
67 /// # Returns
68 /// Returns the transformed or original context based on the implementation.
69 fn call( &self, storage : Definition::Storage, context : core::option::Option< Definition::Context > ) -> Definition::Formed;
70}
71
72impl< Definition, F > FormingEnd< Definition > for F
73where
74 F : Fn( Definition::Storage, core::option::Option< Definition::Context > ) -> Definition::Formed,
75 Definition : crate::FormerDefinitionTypes,
76{
77 #[ inline( always ) ]
78 fn call( &self, storage : Definition::Storage, context : core::option::Option< Definition::Context > ) -> Definition::Formed
79 {
80 self( storage, context )
81 }
82}
83
84/// A `FormingEnd` implementation that directly returns the formed collection as the final product of the forming process.
85///
86/// This struct is particularly useful when the end result of the forming process is simply the formed collection itself,
87/// without needing to integrate or process additional contextual information. It's ideal for scenarios where the final
88/// entity is directly derived from the storage state without further transformations or context-dependent adjustments.
89#[ derive( Debug, Default ) ]
90pub struct ReturnPreformed;
91
92impl< Definition > FormingEnd< Definition > for ReturnPreformed
93where
94 Definition::Storage : crate::StoragePreform< Preformed = Definition::Formed >,
95 Definition : crate::FormerDefinitionTypes,
96{
97 /// Transforms the storage into its final formed state and returns it, bypassing context processing.
98 #[ inline( always ) ]
99 fn call( &self, storage : Definition::Storage, _context : core::option::Option< Definition::Context > ) -> Definition::Formed
100 {
101 crate::StoragePreform::preform( storage )
102 }
103}
104
105/// A `FormingEnd` implementation that returns the storage itself as the formed entity, disregarding any contextual data.
106///
107/// This struct is suited for straightforward forming processes where the storage already represents the final state of the
108/// entity, and no additional processing or transformation of the storage is required. It simplifies use cases where the
109/// storage does not undergo a transformation into a different type at the end of the forming process.
110#[ derive( Debug, Default ) ]
111pub struct ReturnStorage;
112
113impl< Definition, T > FormingEnd< Definition > for ReturnStorage
114where
115 Definition : crate::FormerDefinitionTypes< Context = (), Storage = T, Formed = T >,
116{
117 /// Returns the storage as the final product of the forming process, ignoring any additional context.
118 #[ inline( always ) ]
119 fn call( &self, storage : Definition::Storage, _context : core::option::Option< () > ) -> Definition::Formed
120 {
121 storage
122 }
123}
124
125/// A placeholder `FormingEnd` used when no end operation is required or applicable.
126///
127/// This implementation is useful in generic or templated scenarios where a `FormingEnd` is required by the interface,
128/// but no meaningful end operation is applicable. It serves a role similar to `core::marker::PhantomData` by filling
129/// generic parameter slots without contributing operational logic.
130#[ derive( Debug, Default ) ]
131pub struct NoEnd;
132
133impl< Definition > FormingEnd< Definition > for NoEnd
134where
135 Definition : crate::FormerDefinitionTypes,
136{
137 /// Intentionally causes a panic if called, as its use indicates a configuration error.
138 #[ inline( always ) ]
139 fn call( &self, _storage : Definition::Storage, _context : core::option::Option< Definition::Context > ) -> Definition::Formed
140 {
141 unreachable!();
142 }
143}
144
145#[ allow( unused_extern_crates ) ]
146#[ cfg( all( feature = "no_std", feature = "use_alloc" ) ) ]
147extern crate alloc;
148#[ cfg( all( feature = "no_std", feature = "use_alloc" ) ) ]
149use alloc::boxed::Box;
150
151/// A wrapper around a closure to be used as a `FormingEnd`.
152///
153/// This struct allows for dynamic dispatch of a closure that matches the
154/// `FormingEnd` trait's `call` method signature. It is useful for cases where
155/// a closure needs to be stored or passed around as an object implementing
156/// `FormingEnd`.
157#[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ]
158#[ allow( clippy::type_complexity ) ]
159pub struct FormingEndClosure< Definition : crate::FormerDefinitionTypes >
160{
161 closure : Box< dyn Fn( Definition::Storage, Option< Definition::Context > ) -> Definition::Formed >,
162 _marker : core::marker::PhantomData< Definition::Storage >,
163}
164
165#[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ]
166impl< T, Definition > From< T > for FormingEndClosure< Definition >
167where
168 T : Fn( Definition::Storage, Option< Definition::Context > ) -> Definition::Formed + 'static,
169 Definition : crate::FormerDefinitionTypes,
170{
171 #[ inline( always ) ]
172 fn from( closure : T ) -> Self
173 {
174 Self
175 {
176 closure : Box::new( closure ),
177 _marker : core::marker::PhantomData,
178 }
179 }
180}
181
182#[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ]
183impl< Definition : crate::FormerDefinitionTypes > FormingEndClosure< Definition >
184{
185 /// Constructs a new `FormingEndClosure` with the provided closure.
186 ///
187 /// # Parameters
188 ///
189 /// * `closure` - A closure that matches the expected signature for transforming a collection
190 /// and context into a new context. This closure is stored and called by the
191 /// `call` method of the `FormingEnd` trait implementation.
192 ///
193 /// # Returns
194 ///
195 /// Returns an instance of `FormingEndClosure` encapsulating the provided closure.
196 pub fn new( closure : impl Fn( Definition::Storage, Option< Definition::Context > ) -> Definition::Formed + 'static ) -> Self
197 {
198 Self
199 {
200 closure : Box::new( closure ),
201 _marker : core::marker::PhantomData,
202 }
203 }
204}
205
206#[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ]
207use core::fmt;
208#[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ]
209impl< Definition : crate::FormerDefinitionTypes > fmt::Debug for FormingEndClosure< Definition >
210{
211 fn fmt( &self, f : &mut fmt::Formatter< '_ > ) -> fmt::Result
212 {
213 f.debug_struct( "FormingEndClosure" )
214 .field( "closure", &format_args! { "- closure -" } )
215 .field( "_marker", &self._marker )
216 .finish()
217 }
218}
219
220#[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ]
221impl< Definition : crate::FormerDefinitionTypes > FormingEnd< Definition > for FormingEndClosure< Definition >
222{
223 fn call( &self, storage : Definition::Storage, context : Option< Definition::Context > ) -> Definition::Formed
224 {
225 ( self.closure )( storage, context )
226 }
227}
228
229/// A trait for initiating a structured subforming process with contextual and intermediary storage linkage.
230///
231/// This trait is crucial for the `derive(Former)` macro implementation, where it facilitates the creation
232/// of a subformer that integrates seamlessly within a builder pattern chain. It handles intermediary storage
233/// to accumulate state or data before finally transforming it into the final `Formed` structure.
234///
235/// `FormerBegin` is particularly important in scenarios where complex, hierarchical structures are formed,
236/// allowing a former to be reused within another former. This reusability and the ability to maintain both transient
237/// state (`Storage`) and contextual information (`Context`) are essential for multi-step construction or transformation
238/// processes that culminate in the generation of a final product (`Formed`).
239///
240/// During code generation via the `derive(Former)` macro, `FormerBegin` provides the necessary scaffolding to
241/// initiate the subforming process. This setup is critical for ensuring that all elements involved in the formation
242/// are aligned from the onset, particularly when one former is nested within another, facilitating the creation
243/// of complex hierarchical data structures.
244///
245pub trait FormerBegin< 'storage, Definition >
246where
247 Definition : crate::FormerDefinition,
248 Definition::Storage : 'storage,
249 Definition::Context : 'storage,
250 Definition::End : 'storage,
251{
252 /// Launches the subforming process with an initial storage and context, setting up an `on_end` completion handler.
253 ///
254 /// This method initializes the formation process by providing the foundational elements necessary for
255 /// building the entity. It allows for the configuration of initial states and contextual parameters, which
256 /// are critical for accurately reflecting the intended final state of the entity.
257 ///
258 /// # Parameters
259 ///
260 /// * `storage` - An optional initial state for the intermediary storage structure. This parameter allows
261 /// for the pre-configuration of storage, which can be crucial for entities requiring specific initial states.
262 /// * `context` - An optional initial setting providing contextual information for the subforming process.
263 /// This context can influence how the formation process progresses, especially in complex forming scenarios.
264 /// * `on_end` - A completion handler responsible for transforming the accumulated `Storage` into the final `Formed` structure.
265 /// This parameter is vital for ensuring that the transition from `Storage` to `Formed` is handled correctly,
266 /// incorporating any last-minute adjustments or validations necessary for the entity's integrity.
267 ///
268 /// # Returns
269 ///
270 /// Returns an instance of Former.
271 ///
272 fn former_begin
273 (
274 storage : core::option::Option< Definition::Storage >,
275 context : core::option::Option< Definition::Context >,
276 on_end : Definition::End,
277 ) -> Self;
278}