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}