anda_db_utils/
lib.rs

1use core::ops::Deref;
2use serde::{
3    de::{Deserialize, DeserializeOwned, Deserializer},
4    ser::{Serialize, Serializer},
5};
6use std::{collections::HashSet, hash::Hash};
7
8/// A trait for functional-style method chaining.
9///
10/// Allows any value to be passed through a function, enabling
11/// fluent interfaces and functional programming patterns.
12pub trait Pipe<T> {
13    /// Passes the value through a function.
14    ///
15    /// # Arguments
16    ///
17    /// * `f` - Function to apply to the value
18    ///
19    /// # Returns
20    ///
21    /// The result of applying the function to the value
22    fn pipe<F, R>(self, f: F) -> R
23    where
24        F: FnOnce(Self) -> R,
25        Self: Sized;
26}
27
28impl<T> Pipe<T> for T {
29    fn pipe<F, R>(self, f: F) -> R
30    where
31        F: FnOnce(Self) -> R,
32    {
33        f(self)
34    }
35}
36
37/// A helper utility to efficiently push or extend a `Vec` with unique items.
38///
39/// This struct maintains an internal `HashSet` to keep track of existing items,
40/// providing an optimized way to perform multiple non-existent insertions.
41/// It is designed to be used with a `Vec` that it helps manage.
42///
43/// # Examples
44///
45/// ```rust
46/// use anda_db_utils::UniqueVec;
47///
48/// let vec = vec![1, 2, 3];
49/// let mut extender = UniqueVec::from(vec);
50///
51/// // Push an item that already exists (no change)
52/// extender.push(2);
53/// assert_eq!(extender.as_ref(), &[1, 2, 3]);
54///
55/// // Push a new item
56/// extender.push(4);
57/// assert_eq!(extender.as_ref(), &[1, 2, 3, 4]);
58///
59/// // Extend with a list of items
60/// extender.extend(vec![3, 5, 6]);
61/// assert_eq!(extender.as_ref(), &[1, 2, 3, 4, 5, 6]);
62/// ```
63#[derive(Clone, Debug)]
64pub struct UniqueVec<T> {
65    set: HashSet<T>,
66    vec: Vec<T>,
67}
68
69impl<T> Default for UniqueVec<T> {
70    /// Creates an empty `UniqueVec`.
71    fn default() -> Self {
72        Self {
73            set: HashSet::new(),
74            vec: Vec::new(),
75        }
76    }
77}
78
79impl<T> From<Vec<T>> for UniqueVec<T>
80where
81    T: Eq + Hash + Clone,
82{
83    /// Creates a `UniqueVec` from a `Vec`.
84    ///
85    /// The extender is initialized with all the unique items from the vector.
86    fn from(vec: Vec<T>) -> Self {
87        let set: HashSet<T> = vec.iter().cloned().collect();
88        if set.len() == vec.len() {
89            return Self { set, vec };
90        };
91        let mut this = Self::default();
92        this.extend(vec);
93        this
94    }
95}
96
97impl<T> FromIterator<T> for UniqueVec<T>
98where
99    T: Eq + Hash + Clone,
100{
101    /// Creates a `UniqueVec` from an iterator.
102    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
103        let vec: Vec<T> = iter.into_iter().collect();
104        vec.into()
105    }
106}
107
108impl<T> From<UniqueVec<T>> for Vec<T> {
109    /// Converts a `UniqueVec` into a `Vec`.
110    fn from(extender: UniqueVec<T>) -> Self {
111        extender.vec
112    }
113}
114
115impl<T> AsRef<[T]> for UniqueVec<T> {
116    /// Returns a slice containing the entire vector.
117    fn as_ref(&self) -> &[T] {
118        &self.vec
119    }
120}
121
122impl<T> Deref for UniqueVec<T> {
123    type Target = Vec<T>;
124
125    /// Dereferences the `UniqueVec` to a `Vec`.
126    fn deref(&self) -> &Self::Target {
127        &self.vec
128    }
129}
130
131impl<T> UniqueVec<T>
132where
133    T: Eq + Hash + Clone,
134{
135    /// Creates a new, empty `UniqueVec`.
136    pub fn new() -> Self {
137        UniqueVec::default()
138    }
139
140    /// Creates a new, empty `UniqueVec` with a specified capacity.
141    pub fn with_capacity(capacity: usize) -> Self {
142        UniqueVec {
143            set: HashSet::with_capacity(capacity),
144            vec: Vec::with_capacity(capacity),
145        }
146    }
147
148    /// Returns `true` if the `UniqueVec` contains the specified item.
149    pub fn contains(&self, item: &T) -> bool {
150        self.set.contains(item)
151    }
152
153    /// Pushes an item to the vector if it does not already exist.
154    ///
155    /// # Arguments
156    ///
157    /// * `item` - The item to add.
158    ///
159    /// # Returns
160    ///
161    /// `true` if the item was added, `false` otherwise.
162    pub fn push(&mut self, item: T) -> bool {
163        if self.set.insert(item.clone()) {
164            self.vec.push(item);
165            true
166        } else {
167            false
168        }
169    }
170
171    /// Extends the vector with items from an iterator that do not already exist.
172    ///
173    /// # Arguments
174    ///
175    /// * `items` - An iterator providing the items to add.
176    pub fn extend(&mut self, items: impl IntoIterator<Item = T>) {
177        self.vec.extend(
178            items
179                .into_iter()
180                .filter(|item| self.set.insert(item.clone())),
181        );
182    }
183
184    /// Retains only the elements specified by the predicate.
185    pub fn retain<F>(&mut self, mut f: F)
186    where
187        F: FnMut(&T) -> bool,
188    {
189        self.set.retain(&mut f);
190        self.vec.retain(&mut f);
191    }
192
193    /// Removes and returns the element at `index`.
194    pub fn remove(&mut self, index: usize) -> T {
195        let item = self.vec.remove(index);
196        self.set.remove(&item);
197        item
198    }
199
200    /// Removes **an element** from the vector and returns it.
201    /// The first element that satisfies the predicate will be removed.
202    pub fn remove_if<P>(&mut self, mut predicate: P) -> Option<T>
203    where
204        P: FnMut(&T) -> bool,
205    {
206        if let Some(index) = self.vec.iter().position(&mut predicate) {
207            let item = self.vec.remove(index);
208            self.set.remove(&item);
209            Some(item)
210        } else {
211            None
212        }
213    }
214
215    /// Removes **an element** from the vector and returns it.
216    /// The last element is swapped into its place.
217    pub fn swap_remove_if<P>(&mut self, mut predicate: P) -> Option<T>
218    where
219        P: FnMut(&T) -> bool,
220    {
221        if let Some(index) = self.vec.iter().position(&mut predicate) {
222            let item = self.vec.swap_remove(index);
223            self.set.remove(&item);
224            Some(item)
225        } else {
226            None
227        }
228    }
229
230    /// Intersects the `UniqueVec` with another `UniqueVec`.
231    pub fn intersect_with<'a>(&'a mut self, other: &'a UniqueVec<T>) {
232        self.set = self.set.intersection(&other.set).cloned().collect();
233        self.vec.retain(|item| self.set.contains(item));
234    }
235
236    /// Returns the inner `Vec` of the `UniqueVec`.
237    pub fn into_vec(self) -> Vec<T> {
238        self.vec
239    }
240
241    /// Returns the inner `HashSet` of the `UniqueVec`.
242    pub fn into_set(self) -> HashSet<T> {
243        self.set
244    }
245
246    /// Converts the `UniqueVec` to a `Vec`.
247    pub fn to_vec(&self) -> Vec<T> {
248        self.vec.clone()
249    }
250
251    /// Converts the `UniqueVec` to a `HashSet`.
252    pub fn to_set(&self) -> HashSet<T> {
253        self.set.clone()
254    }
255}
256
257impl<T> Serialize for UniqueVec<T>
258where
259    T: Eq + Hash + Clone + Serialize,
260{
261    /// Serializes the `UniqueVec` as a sequence.
262    #[inline]
263    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
264        serializer.collect_seq(self.vec.iter())
265    }
266}
267
268impl<'de, T> Deserialize<'de> for UniqueVec<T>
269where
270    T: Eq + Hash + Clone + DeserializeOwned,
271{
272    /// Deserializes a sequence into a `UniqueVec`.
273    #[inline]
274    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
275        let vec: Vec<T> = Deserialize::deserialize(deserializer)?;
276        Ok(UniqueVec::from(vec))
277    }
278}
279
280/// Utility for counting the size of serialized CBOR data.
281pub struct CountingWriter {
282    count: usize,
283}
284
285impl Default for CountingWriter {
286    /// Creates a new `CountingWriter` with a count of 0.
287    fn default() -> Self {
288        Self::new()
289    }
290}
291
292impl CountingWriter {
293    /// Creates a new `CountingWriter`.
294    pub fn new() -> Self {
295        CountingWriter { count: 0 }
296    }
297
298    /// Returns the current count of bytes written.
299    pub fn size(&self) -> usize {
300        self.count
301    }
302
303    /// Counts the size of a serializable value in CBOR format.
304    ///
305    /// # Arguments
306    ///
307    /// * `val` - The value to serialize and count.
308    ///
309    /// # Returns
310    ///
311    /// The size of the serialized value in bytes.
312    pub fn count_cbor(val: &impl Serialize) -> usize {
313        let mut writer = CountingWriter::new();
314        // Errors are ignored as CountingWriter::write never fails.
315        let _ = ciborium::into_writer(val, &mut writer);
316        writer.count
317    }
318}
319
320impl std::io::Write for CountingWriter {
321    /// Implements the write method for the Write trait.
322    /// This simply counts the bytes without actually writing them.
323    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
324        let len = buf.len();
325        self.count += len;
326        Ok(len)
327    }
328
329    /// Implements the flush method for the Write trait.
330    /// This is a no-op since we're not actually writing data.
331    fn flush(&mut self) -> std::io::Result<()> {
332        Ok(())
333    }
334}
335
336#[cfg(test)]
337mod tests {
338    use super::*;
339    use std::io::Write;
340
341    #[test]
342    fn test_pipe_trait() {
343        // Test basic pipe functionality
344        let result = 5.pipe(|x| x * 2).pipe(|x| x + 1);
345        assert_eq!(result, 11);
346
347        // Test pipe with different types
348        let string_result = "hello"
349            .pipe(|s| s.to_uppercase())
350            .pipe(|s| format!("{} world", s));
351        assert_eq!(string_result, "HELLO world");
352
353        // Test pipe with closure that changes type
354        let vec_result = vec![1, 2, 3].pipe(|v| v.len()).pipe(|len| len as f64);
355        assert_eq!(vec_result, 3.0);
356    }
357
358    #[test]
359    fn test_unique_vec_new() {
360        let uv: UniqueVec<i32> = UniqueVec::new();
361        assert_eq!(uv.len(), 0);
362        assert!(uv.is_empty());
363    }
364
365    #[test]
366    fn test_unique_vec_with_capacity() {
367        let uv: UniqueVec<i32> = UniqueVec::with_capacity(10);
368        assert_eq!(uv.len(), 0);
369        assert_eq!(uv.capacity(), 10);
370    }
371
372    #[test]
373    fn test_unique_vec_from_vec() {
374        let vec = vec![1, 2, 2, 3, 2, 1];
375        let uv = UniqueVec::from(vec);
376        assert_eq!(uv.len(), 3);
377        assert!(uv.contains(&1));
378        assert!(uv.contains(&2));
379        assert!(uv.contains(&3));
380    }
381
382    #[test]
383    fn test_unique_vec_from_iterator() {
384        let uv: UniqueVec<i32> = [2, 2, 1, 3, 2, 1].iter().cloned().collect();
385        assert_eq!(uv.len(), 3);
386        assert!(uv.contains(&2));
387        assert!(uv.contains(&1));
388        assert!(uv.contains(&3));
389    }
390
391    #[test]
392    fn test_unique_vec_push() {
393        let mut uv = UniqueVec::new();
394
395        // Push new items
396        assert!(uv.push(1));
397        assert!(uv.push(2));
398        assert!(uv.push(3));
399        assert_eq!(uv.len(), 3);
400
401        // Push duplicate items
402        assert!(!uv.push(1));
403        assert!(!uv.push(2));
404        assert_eq!(uv.len(), 3);
405
406        // Verify order is maintained
407        assert_eq!(uv.as_ref(), &[1, 2, 3]);
408    }
409
410    #[test]
411    fn test_unique_vec_extend() {
412        let mut uv = UniqueVec::from(vec![1, 2, 3]);
413
414        // Extend with mix of new and existing items
415        uv.extend(vec![3, 4, 5, 2, 6]);
416
417        assert_eq!(uv.len(), 6);
418        assert_eq!(uv.as_ref(), &[1, 2, 3, 4, 5, 6]);
419    }
420
421    #[test]
422    fn test_unique_vec_retain() {
423        let mut uv = UniqueVec::from(vec![1, 2, 3, 4, 5]);
424
425        // Retain only even numbers
426        uv.retain(|&x| x % 2 == 0);
427
428        assert_eq!(uv.len(), 2);
429        assert_eq!(uv.as_ref(), &[2, 4]);
430        assert!(uv.contains(&2));
431        assert!(uv.contains(&4));
432        assert!(!uv.contains(&1));
433        assert!(!uv.contains(&3));
434        assert!(!uv.contains(&5));
435    }
436
437    #[test]
438    fn test_unique_vec_remove() {
439        let mut uv = UniqueVec::from(vec![1, 2, 3, 4, 5]);
440
441        let removed = uv.remove(2); // Remove element at index 2 (value 3)
442        assert_eq!(removed, 3);
443        assert_eq!(uv.len(), 4);
444        assert_eq!(uv.as_ref(), &[1, 2, 4, 5]);
445        assert!(!uv.contains(&3));
446    }
447
448    #[test]
449    #[should_panic]
450    fn test_unique_vec_remove_out_of_bounds() {
451        let mut uv = UniqueVec::from(vec![1, 2, 3]);
452        uv.remove(5); // Should panic
453    }
454
455    #[test]
456    fn test_unique_vec_remove_if() {
457        let mut uv = UniqueVec::from(vec![1, 2, 3, 4, 5]);
458
459        // Remove first even number
460        let removed = uv.remove_if(|&x| x % 2 == 0);
461        assert_eq!(removed, Some(2));
462        assert_eq!(uv.len(), 4);
463        assert_eq!(uv.as_ref(), &[1, 3, 4, 5]);
464        assert!(!uv.contains(&2));
465
466        // Try to remove non-existent condition
467        let removed = uv.remove_if(|&x| x > 10);
468        assert_eq!(removed, None);
469        assert_eq!(uv.len(), 4);
470    }
471
472    #[test]
473    fn test_unique_vec_swap_remove_if() {
474        let mut uv = UniqueVec::from(vec![1, 2, 3, 4, 5]);
475
476        // Remove first even number (swap with last)
477        let removed = uv.swap_remove_if(|&x| x % 2 == 0);
478        assert_eq!(removed, Some(2));
479        assert_eq!(uv.len(), 4);
480        // After swap_remove, the last element (5) should be in position of removed element
481        assert_eq!(uv.as_ref(), &[1, 5, 3, 4]);
482        assert!(!uv.contains(&2));
483    }
484
485    #[test]
486    fn test_unique_vec_contains() {
487        let uv = UniqueVec::from(vec![1, 2, 3]);
488
489        assert!(uv.contains(&1));
490        assert!(uv.contains(&2));
491        assert!(uv.contains(&3));
492        assert!(!uv.contains(&4));
493    }
494
495    #[test]
496    fn test_unique_vec_intersect_with() {
497        let mut uv1 = UniqueVec::from(vec![1, 2, 3, 4, 5]);
498        let uv2 = UniqueVec::from(vec![3, 4, 5, 6, 7]);
499
500        uv1.intersect_with(&uv2);
501
502        assert_eq!(uv1.len(), 3);
503        assert!(uv1.contains(&3));
504        assert!(uv1.contains(&4));
505        assert!(uv1.contains(&5));
506        assert!(!uv1.contains(&1));
507        assert!(!uv1.contains(&2));
508    }
509
510    #[test]
511    fn test_unique_vec_to_vec() {
512        let uv = UniqueVec::from(vec![1, 2, 2, 3]);
513        let vec = uv.to_vec();
514        assert_eq!(vec, vec![1, 2, 3]);
515    }
516
517    #[test]
518    fn test_unique_vec_to_set() {
519        let uv = UniqueVec::from(vec![1, 2, 3]);
520        let set = uv.to_set();
521        assert_eq!(set.len(), 3);
522        assert!(set.contains(&1));
523        assert!(set.contains(&2));
524        assert!(set.contains(&3));
525    }
526
527    #[test]
528    fn test_unique_vec_as_ref() {
529        let uv = UniqueVec::from(vec![1, 2, 3]);
530        let slice: &[i32] = uv.as_ref();
531        assert_eq!(slice, &[1, 2, 3]);
532    }
533
534    #[test]
535    fn test_unique_vec_deref() {
536        let uv = UniqueVec::from(vec![1, 2, 3]);
537        // Test deref by calling Vec methods directly
538        assert_eq!(uv.len(), 3);
539        assert_eq!(uv[0], 1);
540        assert_eq!(uv[1], 2);
541        assert_eq!(uv[2], 3);
542    }
543
544    #[test]
545    fn test_unique_vec_into_vec() {
546        let uv = UniqueVec::from(vec![1, 2, 3]);
547        let vec: Vec<i32> = uv.into();
548        assert_eq!(vec, vec![1, 2, 3]);
549    }
550
551    #[test]
552    fn test_unique_vec_serialize_deserialize() {
553        let uv = UniqueVec::from(vec![1, 2, 2, 3, 2, 1]); // Duplicates should be removed
554
555        // Serialize
556        let json = serde_json::to_string(&uv).unwrap();
557        assert_eq!(json, "[1,2,3]");
558
559        // Deserialize
560        let deserialized: UniqueVec<i32> = serde_json::from_str("[1,3,2,3,3,2,1]").unwrap();
561        assert_eq!(deserialized.len(), 3);
562        assert_eq!(deserialized.as_ref(), &[1, 3, 2]);
563    }
564
565    #[test]
566    fn test_unique_vec_clone() {
567        let uv1 = UniqueVec::from(vec![1, 2, 3]);
568        let uv2 = uv1.clone();
569
570        assert_eq!(uv1.len(), uv2.len());
571        assert_eq!(uv1.as_ref(), uv2.as_ref());
572    }
573
574    #[test]
575    fn test_counting_writer_new() {
576        let writer = CountingWriter::new();
577        assert_eq!(writer.size(), 0);
578    }
579
580    #[test]
581    fn test_counting_writer_default() {
582        let writer = CountingWriter::default();
583        assert_eq!(writer.size(), 0);
584    }
585
586    #[test]
587    fn test_counting_writer_write() {
588        let mut writer = CountingWriter::new();
589
590        let result = writer.write(b"hello");
591        assert!(result.is_ok());
592        assert_eq!(result.unwrap(), 5);
593        assert_eq!(writer.size(), 5);
594
595        let result = writer.write(b" world");
596        assert!(result.is_ok());
597        assert_eq!(result.unwrap(), 6);
598        assert_eq!(writer.size(), 11);
599    }
600
601    #[test]
602    fn test_counting_writer_flush() {
603        let mut writer = CountingWriter::new();
604        let result = writer.flush();
605        assert!(result.is_ok());
606        assert_eq!(writer.size(), 0); // Flush doesn't change size
607    }
608
609    #[test]
610    fn test_counting_writer_count_cbor() {
611        // Test with simple values
612        let size = CountingWriter::count_cbor(&42i32);
613        assert!(size > 0);
614
615        let size = CountingWriter::count_cbor(&"hello");
616        assert!(size > 0);
617
618        // Test with complex structure
619        let data = vec![1, 2, 3, 4, 5];
620        let size = CountingWriter::count_cbor(&data);
621        assert!(size > 0);
622
623        // Larger data should have larger size
624        let larger_data = vec![1; 100];
625        let larger_size = CountingWriter::count_cbor(&larger_data);
626        assert!(larger_size > size);
627    }
628
629    #[test]
630    fn test_counting_writer_multiple_writes() {
631        let mut writer = CountingWriter::new();
632
633        // Multiple writes should accumulate
634        writer.write_all(b"a").unwrap();
635        assert_eq!(writer.size(), 1);
636
637        writer.write_all(b"bc").unwrap();
638        assert_eq!(writer.size(), 3);
639
640        writer.write_all(b"defg").unwrap();
641        assert_eq!(writer.size(), 7);
642    }
643
644    #[test]
645    fn test_counting_writer_empty_write() {
646        let mut writer = CountingWriter::new();
647
648        let result = writer.write(b"");
649        assert!(result.is_ok());
650        assert_eq!(result.unwrap(), 0);
651        assert_eq!(writer.size(), 0);
652    }
653
654    #[test]
655    fn test_unique_vec_edge_cases() {
656        // Test with empty vector
657        let uv = UniqueVec::from(vec![] as Vec<i32>);
658        assert_eq!(uv.len(), 0);
659        assert!(uv.is_empty());
660
661        // Test with single element
662        let mut uv = UniqueVec::from(vec![42]);
663        assert_eq!(uv.len(), 1);
664        assert!(uv.contains(&42));
665
666        // Test removing the only element
667        let removed = uv.remove(0);
668        assert_eq!(removed, 42);
669        assert_eq!(uv.len(), 0);
670        assert!(!uv.contains(&42));
671    }
672
673    #[test]
674    fn test_unique_vec_string_type() {
675        let mut uv = UniqueVec::new();
676
677        uv.push("hello".to_string());
678        uv.push("world".to_string());
679        uv.push("hello".to_string()); // Duplicate
680
681        assert_eq!(uv.len(), 2);
682        assert!(uv.contains(&"hello".to_string()));
683        assert!(uv.contains(&"world".to_string()));
684    }
685}