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/// Internal namespace.
9mod private
10{
11
12  use crate::*;
13
14  /// Facilitates the conversion of collection entries to their corresponding value representations.
15  ///
16  /// This trait is utilized to transform an entry of a collection into a value, abstracting the operation of collections
17  /// like vectors or hash maps. It ensures that even in complex collection structures, entries can be seamlessly managed
18  /// and manipulated as values.
19  pub trait EntryToVal< Collection >
20  {
21    /// The type of values stored in the collection. This might be distinct from `Entry` in complex collections.
22    /// For example, in a `HashMap`, while `Entry` might be a ( key, value ) tuple, `Val` might only be the value part.
23    type Val;
24
25    /// Converts an entry into a value representation specific to the type of collection. This conversion is crucial
26    /// for handling operations on entries, especially when they need to be treated or accessed as individual values,
27    /// such as retrieving the value part from a key-value pair in a hash map.
28    fn entry_to_val( self ) -> Self::Val;
29  }
30
31  impl< C, E > EntryToVal< C > for E
32  where
33    C : Collection< Entry = E >,
34  {
35    type Val = C::Val;
36
37    fn entry_to_val( self ) -> Self::Val
38    {
39      C::entry_to_val( self )
40    }
41  }
42
43  /// Provides a mechanism for transforming a value back into a collection-specific entry format.
44  ///
45  /// This trait is particularly valuable in scenarios where the operations on a collection require
46  /// not just the manipulation of values but also the re-integration of these values as entries.
47  /// It is especially crucial in complex data structures, such as `HashMap`s, where entries
48  /// often involve a key-value pair, and simple values need to be restructured to fit this model
49  /// for operations like insertion or update.
50
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;
97
98    /// Transforms the instance (value) into an entry compatible with the specified collection.
99    /// This conversion is essential for operations like insertion or modification within the collection,
100    /// where the value needs to be formatted as an entry.
101    ///
102    /// # Returns
103    /// Returns the entry constructed from the instance of the value, ready for integration into the collection.
104    ///
105    /// # Example
106    /// ```
107    /// use former_types::ValToEntry; // use crate `former` instead of crate `former_types` unless you need to use crate `former_types` directly
108    ///
109    /// struct PairMap;
110    ///
111    /// impl ValToEntry< PairMap > for (i32, i32)
112    /// {
113    ///   type Entry = ( String, i32 );
114    ///
115    ///   fn val_to_entry( self ) -> Self::Entry
116    ///   {
117    ///     (self.0.to_string(), self.1)
118    ///   }
119    /// }
120    /// ```
121    fn val_to_entry( self ) -> Self::Entry;
122  }
123
124  impl< C, Val > ValToEntry< C > for Val
125  where
126    C : CollectionValToEntry< Val >,
127  {
128    type Entry = C::Entry;
129
130    /// Invokes the `val_to_entry` function of the `CollectionValToEntry` trait to convert the value to an entry.
131    fn val_to_entry( self ) -> C::Entry
132    {
133      C::val_to_entry( self )
134    }
135  }
136
137  /// Represents a collection by defining the types of entries and values it handles.
138  ///
139  /// This trait abstracts the nature of collections in data structures, facilitating the handling of contained
140  /// entries and values, especially in scenarios where the structure of the collection allows for complex relationships,
141  /// such as `HashMap`s. It not only identifies what constitutes an entry and a value in the context of the collection
142  /// but also provides utility for converting between these two, which is critical in operations involving entry manipulation
143  /// and value retrieval.
144
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    ///   type IntoIter = collection_tools::vec::IntoIter< i32 >;
283    ///   // qqq : zzz : make sure collection_tools has itearators -- done
284    ///
285    ///   fn into_iter( self ) -> Self::IntoIter
286    ///   {
287    ///     self.entries.into_iter() // Create an iterator from the internal HashSet.
288    ///   }
289    /// }
290    ///
291    /// impl CollectionAssign for MyCollection
292    /// {
293    ///   fn assign< Entries >( &mut self, entries : Entries ) -> usize
294    ///   where
295    ///     Entries : IntoIterator< Item = Self::Entry >,
296    ///   {
297    ///     self.entries.clear();
298    ///     self.entries.extend( entries );
299    ///     self.entries.len()
300    ///   }
301    /// }
302    ///
303    /// let mut collection = MyCollection { entries : vec![ 1, 2, 3 ] };
304    /// let new_elements = vec![ 4, 5, 6 ];
305    /// assert_eq!( collection.assign( new_elements ), 3 ); // Collection now contains [ 4, 5, 6 ]
306    /// ```
307    fn assign< Entries >( &mut self, entries : Entries ) -> usize
308    where
309      Entries : IntoIterator< Item = Self::Entry >;
310  }
311
312  // =
313
314  /// A builder structure for constructing collections with a fluent and flexible interface.
315  #[ derive( Default ) ]
316  pub struct CollectionFormer< E, Definition >
317  where
318    Definition : FormerDefinition,
319    Definition::Storage : CollectionAdd< Entry = E >,
320  {
321    storage : Definition::Storage,
322    context : core::option::Option< Definition::Context >,
323    on_end : core::option::Option< Definition::End >,
324  }
325
326  use core::fmt;
327  impl< E, Definition > fmt::Debug for CollectionFormer< E, Definition >
328  where
329    Definition : FormerDefinition,
330    Definition::Storage : CollectionAdd< Entry = E >,
331  {
332    fn fmt( &self, f : &mut fmt::Formatter< '_ > ) -> fmt::Result
333    {
334      f
335      .debug_struct( "CollectionFormer" )
336      .field( "storage", &"Storage Present" )
337      .field( "context", &self.context.as_ref().map( |_| "Context Present" ) )
338      .field( "on_end", &self.on_end.as_ref().map( |_| "End Present" ) )
339      .finish()
340    }
341  }
342
343  impl< E, Definition > CollectionFormer< E, Definition >
344  where
345    Definition : FormerDefinition,
346    Definition::Storage : CollectionAdd< Entry = E >,
347  {
348    /// Begins the construction process of a collection with optional initial storage and context,
349    /// setting up an `on_end` completion handler to finalize the collection's construction.
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    )
357    -> Self
358    {
359      if storage.is_none()
360      {
361        storage = Some( core::default::Default::default() );
362      }
363      Self
364      {
365        storage : storage.unwrap(),
366        context,
367        on_end : Some( on_end ),
368      }
369    }
370
371    /// Provides a variation of the `begin` method allowing for coercion of the end handler,
372    /// facilitating ease of integration with different end conditions.
373    #[ inline( always ) ]
374    pub fn begin_coercing< IntoEnd >
375    (
376      mut storage : core::option::Option< Definition::Storage >,
377      context : core::option::Option< Definition::Context >,
378      on_end : IntoEnd,
379    )
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    #[ inline( always ) ]
398    pub fn end( mut self ) -> Definition::Formed
399    {
400      let on_end = self.on_end.take().unwrap();
401      let context = self.context.take();
402      on_end.call( self.storage, context )
403    }
404
405    /// Alias for the `end` method to align with typical builder pattern terminologies.
406    #[ inline( always ) ]
407    pub fn form( self ) -> Definition::Formed
408    {
409      self.end()
410    }
411
412    /// Replaces the current storage with a provided storage, allowing for resetting or
413    /// redirection of the building process.
414    #[ inline( always ) ]
415    pub fn replace( mut self, storage : Definition::Storage ) -> Self
416    {
417      self.storage = storage;
418      self
419    }
420  }
421
422  impl< E, Storage, Formed, Definition > CollectionFormer< E, Definition >
423  where
424    Definition : FormerDefinition< Context = (), Storage = Storage, Formed = Formed >,
425    Definition::Storage : CollectionAdd< Entry = E >,
426  {
427    /// Constructs a new `CollectionFormer` instance, starting with an empty storage.
428    /// This method serves as the entry point for the builder pattern, facilitating the
429    /// creation of a new collection.
430    #[ inline( always ) ]
431    pub fn new( end : Definition::End ) -> Self
432    {
433      Self::begin
434      (
435        None,
436        None,
437        end,
438      )
439    }
440
441    /// Variant of the `new` method allowing for end condition coercion, providing flexibility
442    /// in specifying different types of end conditions dynamically.
443    #[ inline( always ) ]
444    pub fn new_coercing< IntoEnd >( end : IntoEnd ) -> Self
445    where
446      IntoEnd : Into< Definition::End >,
447    {
448      Self::begin
449      (
450        None,
451        None,
452        end.into(),
453      )
454    }
455  }
456
457  impl< E, Definition > CollectionFormer< E, Definition >
458  where
459    Definition : FormerDefinition,
460    Definition::Storage : CollectionAdd< Entry = E >,
461  {
462
463    /// Appends an entry to the end of the storage, expanding the internal collection.
464    #[ inline( always ) ]
465    pub fn add< IntoElement >( mut self, entry : IntoElement ) -> Self
466    where IntoElement : core::convert::Into< E >,
467    {
468      CollectionAdd::add( &mut self.storage, entry.into() );
469      self
470    }
471
472  }
473
474  //
475
476  impl< E, Definition > FormerBegin< Definition >
477  for CollectionFormer< E, Definition >
478  where
479    Definition : FormerDefinition,
480    Definition::Storage : CollectionAdd< Entry = E >,
481  {
482
483    #[ inline( always ) ]
484    fn former_begin
485    (
486      storage : core::option::Option< Definition::Storage >,
487      context : core::option::Option< Definition::Context >,
488      on_end : Definition::End,
489    )
490    -> Self
491    {
492      Self::begin( storage, context, on_end )
493    }
494
495  }
496
497}
498
499/// Former of a binary tree map.
500mod btree_map;
501/// Former of a binary tree set.
502mod btree_set;
503/// Former of a binary heap.
504mod binary_heap;
505/// Former of a hash map.
506mod hash_map;
507/// Former of a hash set.
508mod hash_set;
509/// Former of a linked list.
510mod linked_list;
511/// Former of a vector.
512mod vector;
513/// Former of a vector deque.
514mod vector_deque;
515
516#[ doc( inline ) ]
517#[ allow( unused_imports ) ]
518pub use own::*;
519
520/// Own namespace of the module.
521#[ allow( unused_imports ) ]
522pub mod own
523{
524  use super::*;
525  #[ doc( inline ) ]
526  pub use orphan::*;
527}
528
529/// Parented namespace of the module.
530#[ allow( unused_imports ) ]
531pub mod orphan
532{
533  use super::*;
534  #[ doc( inline ) ]
535  pub use exposed::*;
536}
537
538/// Exposed namespace of the module.
539#[ allow( unused_imports ) ]
540pub mod exposed
541{
542  use super::*;
543
544  #[ doc( inline ) ]
545  pub use prelude::*;
546
547  #[ doc( inline ) ]
548  pub use private::
549  {
550
551    EntryToVal,
552    CollectionValToEntry,
553    ValToEntry,
554
555    Collection,
556    CollectionAdd,
557    CollectionAssign,
558    CollectionFormer,
559
560  };
561
562  #[ doc( inline ) ]
563  #[ allow( unused_imports ) ]
564  pub use super::
565  {
566    btree_map::*,
567    btree_set::*,
568    binary_heap::*,
569    hash_map::*,
570    hash_set::*,
571    linked_list::*,
572    vector::*,
573    vector_deque::*,
574  };
575
576}
577
578/// Prelude to use essentials: `use my_module::prelude::*`.
579#[ allow( unused_imports ) ]
580pub mod prelude
581{
582  use super::*;
583}