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}