orx_split_vec/growth/recursive/from.rs
1use crate::{Doubling, 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: Clone> 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 SplitVec::from_raw_parts(value.len(), alloc::vec![value.into()], Recursive)
77 }
78}
79
80#[cfg(test)]
81mod tests {
82 use crate::*;
83
84 fn validate<G: Growth>(split: SplitVec<usize, G>)
85 where
86 SplitVec<usize, G>: Into<SplitVec<usize, Recursive>>,
87 {
88 let recursive: SplitVec<_, Recursive> = split.clone().into();
89
90 assert_eq!(split.len(), recursive.len());
91 for i in 0..split.len() {
92 assert_eq!(split.get(i), recursive.get(i));
93 }
94 }
95
96 #[test]
97 fn into_recursive() {
98 let mut vec = alloc::vec![];
99 let mut linear = SplitVec::with_linear_growth(4);
100 let mut doubling = SplitVec::with_doubling_growth();
101
102 for i in 0..879 {
103 vec.push(i);
104 linear.push(i);
105 doubling.push(i);
106 }
107
108 let recursive: SplitVec<_, Recursive> = vec.into();
109
110 validate(recursive);
111 validate(linear);
112 validate(doubling);
113 }
114}