former_types/
collection.rs

1//!
2//! This module defines traits and structures that facilitate the management and manipulation
3//! of collection data structures within a builder pattern context. It provides a comprehensive
4//! interface for adding, managing, and converting elements within various types of collections,
5//! such as vectors, hash maps, and custom collection implementations.
6//!
7
8/// Define a private namespace for all its items.
9mod private
10{
11
12
13  use crate::*;
14
15  /// Facilitates the conversion of collection entries to their corresponding value representations.
16  ///
17  /// This trait is utilized to transform an entry of a collection into a value, abstracting the operation of collections
18  /// like vectors or hash maps. It ensures that even in complex collection structures, entries can be seamlessly managed
19  /// and manipulated as values.
20  pub trait EntryToVal< Collection >
21  {
22    /// The type of values stored in the collection. This might be distinct from `Entry` in complex collections.
23    /// For example, in a `HashMap`, while `Entry` might be a ( key, value ) tuple, `Val` might only be the value part.
24    type Val;
25
26    /// Converts an entry into a value representation specific to the type of collection. This conversion is crucial
27    /// for handling operations on entries, especially when they need to be treated or accessed as individual values,
28    /// such as retrieving the value part from a key-value pair in a hash map.
29    fn entry_to_val( self ) -> Self::Val;
30  }
31
32  impl< C, E > EntryToVal< C > for E
33  where
34    C : Collection< Entry = E >,
35  {
36    type Val = C::Val;
37
38    fn entry_to_val( self ) -> Self::Val
39    {
40      C::entry_to_val( self )
41    }
42  }
43
44  /// Provides a mechanism for transforming a value back into a collection-specific entry format.
45  ///
46  /// This trait is particularly valuable in scenarios where the operations on a collection require
47  /// not just the manipulation of values but also the re-integration of these values as entries.
48  /// It is especially crucial in complex data structures, such as `HashMap`s, where entries
49  /// often involve a key-value pair, and simple values need to be restructured to fit this model
50  /// for operations like insertion or update.
51  pub trait CollectionValToEntry< Val >
52  {
53    /// The specific type of entry that corresponds to the value within the collection.
54    /// For example, in a `HashMap`, this might be a tuple of a key and a value.
55    type Entry;
56
57    /// Converts a value into a collection-specific entry, facilitating operations that modify
58    /// the collection. This method is key for ensuring that values can be correctly integrated
59    /// back into the collection, particularly when the entry type is more complex than the value.
60    ///
61    /// # Parameters
62    /// * `val` - The value to be converted into an entry.
63    ///
64    /// # Returns
65    /// Returns the entry constructed from the provided value, ready for insertion or other modifications.
66    ///
67    /// # Example
68    /// ```
69    /// use former_types::CollectionValToEntry; // use crate `former` instead of crate `former_types` unless you need to use crate `former_types` directly
70    ///
71    /// struct PairMap;
72    ///
73    /// impl CollectionValToEntry< ( i32, i32 ) > for PairMap
74    /// {
75    ///   type Entry = ( String, i32 );
76    ///
77    ///   fn val_to_entry( val : ( i32, i32 ) ) -> Self::Entry
78    ///   {
79    ///     (val.0.to_string(), val.1)
80    ///   }
81    /// }
82    /// ```
83    fn val_to_entry( val : Val ) -> Self::Entry;
84  }
85
86  /// Facilitates the conversion of values back into entries for specific collection types.
87  ///
88  /// This trait wraps the functionality of `CollectionValToEntry`, providing a more ergonomic
89  /// interface for converting values directly within the type they pertain to. It is useful
90  /// in maintaining the integrity of collection operations, especially when dealing with
91  /// sophisticated structures that separate the concept of values and entries, such as `HashMap`s
92  /// and other associative collections.
93  pub trait ValToEntry< Collection >
94  {
95    /// Represents the type of entry that corresponds to the value within the collection.
96    /// Type `Entry` is defined by the `Collection` trait.
97    type Entry;
98
99    /// Transforms the instance (value) into an entry compatible with the specified collection.
100    /// This conversion is essential for operations like insertion or modification within the collection,
101    /// where the value needs to be formatted as an entry.
102    ///
103    /// # Returns
104    /// Returns the entry constructed from the instance of the value, ready for integration into the collection.
105    ///
106    /// # Example
107    /// ```
108    /// use former_types::ValToEntry; // use crate `former` instead of crate `former_types` unless you need to use crate `former_types` directly
109    ///
110    /// struct PairMap;
111    ///
112    /// impl ValToEntry< PairMap > for (i32, i32)
113    /// {
114    ///   type Entry = ( String, i32 );
115    ///
116    ///   fn val_to_entry( self ) -> Self::Entry
117    ///   {
118    ///     (self.0.to_string(), self.1)
119    ///   }
120    /// }
121    /// ```
122    fn val_to_entry( self ) -> Self::Entry;
123  }
124
125  impl< C, Val > ValToEntry< C > for Val
126  where
127    C : CollectionValToEntry< Val >,
128  {
129    type Entry = C::Entry;
130
131    /// Invokes the `val_to_entry` function of the `CollectionValToEntry` trait to convert the value to an entry.
132    fn val_to_entry( self ) -> C::Entry
133    {
134      C::val_to_entry( self )
135    }
136  }
137
138  /// Represents a collection by defining the types of entries and values it handles.
139  ///
140  /// This trait abstracts the nature of collections in data structures, facilitating the handling of contained
141  /// entries and values, especially in scenarios where the structure of the collection allows for complex relationships,
142  /// such as `HashMap`s. It not only identifies what constitutes an entry and a value in the context of the collection
143  /// but also provides utility for converting between these two, which is critical in operations involving entry manipulation
144  /// and value retrieval.
145  pub trait Collection
146  {
147    /// The type of entries that can be added to the collection. This type can differ from `Val` in collections like `HashMap`,
148    /// where an entry might represent a key-value pair, and `Val` could represent just the value or the key.
149    type Entry;
150
151    /// The type of values stored in the collection. This might be distinct from `Entry` in complex collections.
152    /// For example, in a `HashMap`, while `Entry` might be a ( key, value ) tuple, `Val` might only be the value part.
153    type Val;
154
155    /// Converts an entry to its corresponding value within the collection. This function is essential for abstracting
156    /// the collection's internal representation from the values it manipulates.
157    fn entry_to_val( e : Self::Entry ) -> Self::Val;
158  }
159
160  /// Provides functionality to add individual entries to a collection.
161  ///
162  /// This trait extends the basic `Collection` trait by introducing a method to add entries to a collection.
163  /// It is designed to handle the collection's specific requirements and rules for adding entries, such as
164  /// managing duplicates, maintaining order, or handling capacity constraints.
165  pub trait CollectionAdd : Collection
166  {
167    /// Adds an entry to the collection and returns a boolean indicating the success of the operation.
168    ///
169    /// Implementations should ensure that the entry is added according to the rules of the collection,
170    /// which might involve checking for duplicates, ordering, or capacity limits.
171    ///
172    /// # Parameters
173    ///
174    /// * `e`: The entry to be added to the collection, where the type `Entry` is defined by the `Collection` trait.
175    ///
176    /// # Returns
177    ///
178    /// Returns `true` if the entry was successfully added, or `false` if not added due to reasons such as
179    /// the entry already existing in the collection or the collection reaching its capacity.
180    ///
181    /// # Examples
182    ///
183    /// Basic usage:
184    ///
185    /// ```rust
186    ///
187    /// use former_types::{ Collection, CollectionAdd }; // use crate `former` instead of crate `former_types` unless you need to use crate `former_types` directly
188    ///
189    /// struct MyCollection
190    /// {
191    ///   entries : Vec<  i32  >,
192    /// }
193    ///
194    /// impl Collection for MyCollection
195    /// {
196    ///   type Entry = i32;
197    ///   type Val = i32;
198    ///
199    ///   #[ inline( always ) ]
200    ///   fn entry_to_val( e : Self::Entry ) -> Self::Val
201    ///   {
202    ///     e
203    ///   }
204    ///
205    /// }
206    ///
207    /// impl CollectionAdd for MyCollection
208    /// {
209    ///   fn add( &mut self, e : Self::Entry ) -> bool
210    ///   {
211    ///     if self.entries.contains( &e )
212    ///     {
213    ///       false
214    ///     }
215    ///     else
216    ///     {
217    ///       self.entries.push( e );
218    ///       true
219    ///     }
220    ///   }
221    /// }
222    ///
223    /// let mut collection = MyCollection { entries : vec![] };
224    /// assert!( collection.add( 10 ) ); // Returns true, entry added
225    /// assert!( !collection.add( 10 ) ); // Returns false, entry already exists
226    /// ```
227    fn add( &mut self, e : Self::Entry ) -> bool;
228  }
229
230  /// Defines the capability to replace all entries in a collection with a new set of entries.
231  ///
232  /// This trait extends the `Collection` trait by providing a method to replace the existing entries in
233  /// the collection with a new set. This can be useful for resetting the collection's contents or bulk-updating
234  /// them based on external criteria or operations.
235  pub trait CollectionAssign : Collection
236  where
237    Self : IntoIterator< Item = Self::Entry >,
238  {
239    /// Replaces all entries in the collection with the provided entries and returns the count of new entries added.
240    ///
241    /// This method clears the existing entries and populates the collection with new ones provided by an iterator.
242    /// It is ideal for scenarios where the collection needs to be refreshed or updated with a new batch of entries.
243    ///
244    /// # Parameters
245    ///
246    /// * `entries` : An iterator over the entries to be added to the collection. The entries must conform to
247    ///   the `Entry` type defined by the `Collection` trait.
248    ///
249    /// # Returns
250    ///
251    /// Returns the number of entries successfully added to the collection. This count may differ from the total
252    /// number of entries in the iterator if the collection imposes restrictions such as capacity limits or duplicate
253    /// handling.
254    ///
255    /// # Examples
256    ///
257    /// ```rust
258    /// use former_types::{ Collection, CollectionAssign }; // use crate `former` instead of crate `former_types` unless you need to use crate `former_types` directly
259    ///
260    /// struct MyCollection
261    /// {
262    ///   entries : Vec<  i32  >,
263    /// }
264    ///
265    /// impl Collection for MyCollection
266    /// {
267    ///   type Entry = i32;
268    ///   type Val = i32;
269    ///
270    ///   #[ inline( always ) ]
271    ///   fn entry_to_val( e : Self::Entry ) -> Self::Val
272    ///   {
273    ///     e
274    ///   }
275    ///
276    /// }
277    ///
278    /// impl IntoIterator for MyCollection
279    /// {
280    ///   type Item = i32;
281    ///   type IntoIter = std::vec::IntoIter< i32 >;
282    ///   // qqq : zzz : make sure collection_tools has itearators -- done
283    ///
284    ///   fn into_iter( self ) -> Self::IntoIter
285    ///   {
286    ///     self.entries.into_iter() // Create an iterator from the internal HashSet.
287    ///   }
288    /// }
289    ///
290    /// impl CollectionAssign for MyCollection
291    /// {
292    ///   fn assign< Entries >( &mut self, entries : Entries ) -> usize
293    ///   where
294    ///     Entries : IntoIterator< Item = Self::Entry >,
295    ///   {
296    ///     self.entries.clear();
297    ///     self.entries.extend( entries );
298    ///     self.entries.len()
299    ///   }
300    /// }
301    ///
302    /// let mut collection = MyCollection { entries : vec![ 1, 2, 3 ] };
303    /// let new_elements = vec![ 4, 5, 6 ];
304    /// assert_eq!( collection.assign( new_elements ), 3 ); // Collection now contains [ 4, 5, 6 ]
305    /// ```
306    fn assign< Entries >( &mut self, entries : Entries ) -> usize
307    where
308      Entries : IntoIterator< Item = Self::Entry >;
309  }
310
311  // =
312
313  /// A builder structure for constructing collections with a fluent and flexible interface.
314  #[ derive( Default ) ]
315  pub struct CollectionFormer< E, Definition >
316  where
317    Definition : FormerDefinition,
318    Definition::Storage : CollectionAdd< Entry = E >,
319  {
320    storage : Definition::Storage,
321    context : core::option::Option<  Definition::Context  >,
322    on_end : core::option::Option<  Definition::End  >,
323  }
324
325  use core::fmt;
326  impl< E, Definition > fmt::Debug for CollectionFormer< E, Definition >
327  where
328    Definition : FormerDefinition,
329    Definition::Storage : CollectionAdd< Entry = E >,
330  {
331    fn fmt( &self, f : &mut fmt::Formatter< '_ > ) -> fmt::Result
332    {
333      f.debug_struct( "CollectionFormer" )
334        .field( "storage", &"Storage Present" )
335        .field( "context", &self.context.as_ref().map( | _ | "Context Present" ) )
336        .field( "on_end", &self.on_end.as_ref().map( | _ | "End Present" ) )
337        .finish()
338    }
339  }
340
341  impl< E, Definition > CollectionFormer< E, Definition >
342  where
343    Definition : FormerDefinition,
344    Definition::Storage : CollectionAdd< Entry = E >,
345  {
346    /// Begins the construction process of a collection with optional initial storage and context,
347    /// setting up an `on_end` completion handler to finalize the collection's construction.
348    /// # Panics
349    /// qqq: doc
350    #[ inline( always ) ]
351    pub fn begin
352    (
353      mut storage : core::option::Option<  Definition::Storage  >,
354      context : core::option::Option<  Definition::Context  >,
355      on_end : Definition::End,
356    ) -> Self
357    {
358      if storage.is_none()
359      {
360        storage = Some( core::default::Default::default() );
361      }
362      Self
363      {
364        storage : storage.unwrap(),
365        context,
366        on_end : Some( on_end ),
367      }
368    }
369
370    /// Provides a variation of the `begin` method allowing for coercion of the end handler,
371    /// facilitating ease of integration with different end conditions.
372    /// # Panics
373    /// qqq: docs
374    #[ inline( always ) ]
375    pub fn begin_coercing< IntoEnd >
376    (
377      mut storage : core::option::Option<  Definition::Storage  >,
378      context : core::option::Option<  Definition::Context  >,
379      on_end : IntoEnd,
380    ) -> Self
381    where
382      IntoEnd : Into< Definition::End >,
383    {
384      if storage.is_none()
385      {
386        storage = Some( core::default::Default::default() );
387      }
388      Self
389      {
390        storage : storage.unwrap(),
391        context,
392        on_end : Some( on_end.into() ),
393      }
394    }
395
396    /// Finalizes the building process, returning the formed or a context incorporating it.
397    /// # Panics
398    /// qqq: doc
399    #[ inline( always ) ]
400    pub fn end( mut self ) -> Definition::Formed
401    {
402      let on_end = self.on_end.take().unwrap();
403      let context = self.context.take();
404      on_end.call( self.storage, context )
405    }
406
407    /// Alias for the `end` method to align with typical builder pattern terminologies.
408    #[ inline( always ) ]
409    pub fn form( self ) -> Definition::Formed
410    {
411      self.end()
412    }
413
414    /// Replaces the current storage with a provided storage, allowing for resetting or
415    /// redirection of the building process.
416    #[ inline( always ) ]
417    #[ must_use ]
418    pub fn replace( mut self, storage : Definition::Storage ) -> Self
419    {
420      self.storage = storage;
421      self
422    }
423  }
424
425  impl< E, Storage, Formed, Definition > CollectionFormer< E, Definition >
426  where
427    Definition : FormerDefinition< Context = (), Storage = Storage, Formed = Formed >,
428    Definition::Storage : CollectionAdd< Entry = E >,
429  {
430    /// Constructs a new `CollectionFormer` instance, starting with an empty storage.
431    /// This method serves as the entry point for the builder pattern, facilitating the
432    /// creation of a new collection.
433    #[ inline( always ) ]
434    pub fn new( end : Definition::End ) -> Self
435    {
436      Self::begin( None, None, end )
437    }
438
439    /// Variant of the `new` method allowing for end condition coercion, providing flexibility
440    /// in specifying different types of end conditions dynamically.
441    #[ inline( always ) ]
442    pub fn new_coercing< IntoEnd >( end : IntoEnd ) -> Self
443    where
444      IntoEnd : Into< Definition::End >,
445    {
446      Self::begin( None, None, end.into() )
447    }
448  }
449
450  impl< E, Definition > CollectionFormer< E, Definition >
451  where
452    Definition : FormerDefinition,
453    Definition::Storage : CollectionAdd< Entry = E >,
454  {
455    /// Appends an entry to the end of the storage, expanding the internal collection.
456    #[ inline( always ) ]
457    #[ must_use ]
458    #[ allow( clippy::should_implement_trait ) ]
459    pub fn add< IntoElement >( mut self, entry : IntoElement ) -> Self
460    where
461      IntoElement : core::convert::Into< E >,
462    {
463      CollectionAdd::add( &mut self.storage, entry.into() );
464      self
465    }
466  }
467
468  //
469
470  impl< 'a, E, Definition > FormerBegin< 'a, Definition > for CollectionFormer< E, Definition >
471  where
472    Definition : FormerDefinition,
473    Definition::Storage : CollectionAdd< Entry = E > + 'a,
474    Definition::Context : 'a,
475    Definition::End : 'a,
476  {
477    #[ inline( always ) ]
478    fn former_begin
479    (
480      storage : core::option::Option<  Definition::Storage  >,
481      context : core::option::Option<  Definition::Context  >,
482      on_end : Definition::End,
483    ) -> Self
484    {
485      Self::begin( storage, context, on_end )
486    }
487  }
488}
489
490/// Former of a binary heap.
491mod binary_heap;
492/// Former of a binary tree map.
493mod btree_map;
494/// Former of a binary tree set.
495mod btree_set;
496/// Former of a hash map.
497mod hash_map;
498/// Former of a hash set.
499mod hash_set;
500/// Former of a linked list.
501mod linked_list;
502/// Former of a vector.
503mod vector;
504/// Former of a vector deque.
505mod vector_deque;
506
507#[ doc( inline ) ]
508#[ allow( unused_imports ) ]
509pub use own::*;
510
511/// Own namespace of the module.
512#[ allow( unused_imports ) ]
513pub mod own
514{
515  //
516  use super::*;
517  #[ doc( inline ) ]
518  pub use orphan::*;
519}
520
521/// Parented namespace of the module.
522#[ allow( unused_imports ) ]
523pub mod orphan
524{
525  //
526  use super::*;
527  #[ doc( inline ) ]
528  pub use exposed::*;
529}
530
531/// Exposed namespace of the module.
532#[ allow( unused_imports ) ]
533pub mod exposed
534{
535  //
536  use super::*;
537
538  #[ doc( inline ) ]
539  pub use prelude::*;
540
541  #[ doc( inline ) ]
542  pub use private::{ EntryToVal, CollectionValToEntry, ValToEntry, Collection, CollectionAdd, CollectionAssign, CollectionFormer };
543
544  #[ doc( inline ) ]
545  #[ allow( unused_imports ) ]
546  pub use super::{ btree_map::*, btree_set::*, binary_heap::*, hash_map::*, hash_set::*, linked_list::*, vector::*, vector_deque::* };
547}
548
549/// Prelude to use essentials: `use my_module::prelude::*`.
550#[ allow( unused_imports ) ]
551pub mod prelude
552{
553  use super::*;
554}