Skip to main content

orx_split_vec/growth/recursive/
from.rs

1use crate::{Doubling, Fragment, Linear, Recursive, SplitVec};
2use alloc::vec::Vec;
3
4impl<T> From<SplitVec<T, Doubling>> for SplitVec<T, Recursive> {
5    /// Converts a `SplitVec<T, Doubling>` into a `SplitVec<T, Recursive>` with no cost.
6    ///
7    /// * The benefit of `Doubling` growth strategy is its constant random access time.
8    /// * On the other hand, the benefit of `Recursive` growth strategy is the constant time `expand` operation.
9    ///
10    /// Note that this is a one-way conversion:
11    /// * it is possible to convert any split vec `SplitVec<T, Doubling>` into `SplitVec<T, Recursive>`;
12    /// * however, not the other way around, since constant random access time requirements of `Doubling` are not satisfied.
13    ///
14    /// # Examples
15    ///
16    /// ```
17    /// use orx_split_vec::*;
18    ///
19    /// let mut split_vec_doubling = SplitVec::with_doubling_growth();
20    /// split_vec_doubling.extend_from_slice(&['a', 'b', 'c']);
21    /// assert_eq!(split_vec_doubling, &['a', 'b', 'c']);
22    ///
23    /// let split_vec_recursive: SplitVec<_, Recursive> = split_vec_doubling.into();
24    /// assert_eq!(split_vec_recursive, &['a', 'b', 'c']);
25    /// ```
26    fn from(value: SplitVec<T, Doubling>) -> Self {
27        Self::from_raw_parts(value.len, value.fragments, Recursive)
28    }
29}
30
31impl<T> From<SplitVec<T, Linear>> for SplitVec<T, Recursive> {
32    /// Converts a `SplitVec<T, Doubling>` into a `SplitVec<T, Recursive>` with no cost.
33    ///
34    /// * The benefit of `Doubling` growth strategy is its constant random access time.
35    /// * On the other hand, the benefit of `Recursive` growth strategy is the constant time `expand` operation.
36    ///
37    /// Note that this is a one-way conversion:
38    /// * it is possible to convert any split vec `SplitVec<T, Doubling>` into `SplitVec<T, Recursive>`;
39    /// * however, not the other way around, since constant random access time requirements of `Doubling` are not satisfied.
40    ///
41    /// # Examples
42    ///
43    /// ```
44    /// use orx_split_vec::*;
45    ///
46    /// let mut split_vec_linear = SplitVec::with_linear_growth(4);
47    /// split_vec_linear.extend_from_slice(&['a', 'b', 'c']);
48    /// assert_eq!(split_vec_linear, &['a', 'b', 'c']);
49    ///
50    /// let split_vec_recursive: SplitVec<_, Recursive> = split_vec_linear.into();
51    /// assert_eq!(split_vec_recursive, &['a', 'b', 'c']);
52    /// ```
53    fn from(value: SplitVec<T, Linear>) -> Self {
54        Self::from_raw_parts(value.len, value.fragments, Recursive)
55    }
56}
57
58impl<T> From<Vec<T>> for SplitVec<T, Recursive> {
59    /// Converts a `Vec` into a `SplitVec`.
60    ///
61    /// # Examples
62    ///
63    /// ```
64    /// use orx_split_vec::*;
65    ///
66    /// let vec = vec!['a', 'b', 'c'];
67    /// let vec_capacity = vec.capacity();
68    ///
69    /// let split_vec: SplitVec<_, Recursive> = vec.into();
70    ///
71    /// assert_eq!(split_vec, &['a', 'b', 'c']);
72    /// assert_eq!(1, split_vec.fragments().len());
73    /// assert!(vec_capacity <= split_vec.capacity());
74    /// ```
75    fn from(value: Vec<T>) -> Self {
76        let fragment = Fragment::new(Fragment::capacity_of_vec(&value), value);
77        SplitVec::from_raw_parts(fragment.len(), alloc::vec![fragment], Recursive)
78    }
79}
80
81#[cfg(test)]
82mod tests {
83    use crate::*;
84
85    fn validate<G: Growth>(split: SplitVec<usize, G>)
86    where
87        SplitVec<usize, G>: Into<SplitVec<usize, Recursive>>,
88    {
89        let recursive: SplitVec<_, Recursive> = split.clone().into();
90
91        assert_eq!(split.len(), recursive.len());
92        for i in 0..split.len() {
93            assert_eq!(split.get(i), recursive.get(i));
94        }
95    }
96
97    #[test]
98    fn into_recursive() {
99        let mut vec = alloc::vec![];
100        let mut linear = SplitVec::with_linear_growth(4);
101        let mut doubling = SplitVec::with_doubling_growth();
102
103        for i in 0..879 {
104            vec.push(i);
105            linear.push(i);
106            doubling.push(i);
107        }
108
109        let recursive: SplitVec<_, Recursive> = vec.into();
110
111        validate(recursive);
112        validate(linear);
113        validate(doubling);
114    }
115}