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}