Skip to main content

handy/
iter.rs

1use std::fmt::Display;
2
3/// Trait to convert a vector of `T` into a vector of `&T` or `&mut T`
4pub trait IntoRefVec<'a, T> {
5    /// Converts a vector of `T` to a vector of `&mut T`
6    ///
7    /// ## Example
8    ///
9    /// ```rust,no_run
10    /// use handy::iter::IntoRefVec;
11    ///
12    /// let mut x = vec![1, 2, 3];
13    /// let y = x.as_mut_ref_vec();
14    /// assert_eq!(y, vec![&mut 1, &mut 2, &mut 3]);
15    /// ```
16    fn as_mut_ref_vec(&'a mut self) -> Vec<&'a mut T>;
17
18    /// Converts a vector of `T` to a vector of `&T`
19    ///
20    /// ## Example
21    ///
22    /// ```rust,no_run
23    /// use handy::iter::IntoRefVec;
24    ///
25    /// let x = vec![1, 2, 3];
26    /// let y = x.as_ref_vec();
27    /// assert_eq!(y, vec![&1, &2, &3]);
28    /// ```
29    fn as_ref_vec(&'a self) -> Vec<&'a T>;
30}
31
32impl<'a, T> IntoRefVec<'a, T> for Option<Vec<T>> {
33    fn as_mut_ref_vec(&'a mut self) -> Vec<&'a mut T> {
34        self.iter_mut().flat_map(|v| v.iter_mut()).collect()
35    }
36
37    fn as_ref_vec(&'a self) -> Vec<&'a T> {
38        self.iter().flat_map(|v| v.iter()).collect()
39    }
40}
41
42impl<'a, T> IntoRefVec<'a, T> for Vec<T> {
43    fn as_mut_ref_vec(&'a mut self) -> Vec<&'a mut T> {
44        self.iter_mut().collect()
45    }
46
47    fn as_ref_vec(&'a self) -> Vec<&'a T> {
48        self.iter().collect()
49    }
50}
51
52impl<'a, T> IntoRefVec<'a, T> for [T] {
53    fn as_mut_ref_vec(&'a mut self) -> Vec<&'a mut T> {
54        self.iter_mut().collect()
55    }
56
57    fn as_ref_vec(&'a self) -> Vec<&'a T> {
58        self.iter().collect()
59    }
60}
61
62/// Trait for converting an iterable of items that can be displayed into a vector of strings
63pub trait StringIterable {
64    /// Converts the iterable to a vector of strings.
65    ///
66    /// ## Example
67    ///
68    /// ```rust,no_run
69    /// use handy::iter::StringIterable;
70    ///
71    /// let x = vec![1, 2, 3];
72    /// let y = x.to_string_vec();
73    /// assert_eq!(y, vec!["1", "2", "3"]);
74    /// ```
75    fn to_string_vec(&self) -> Vec<String>;
76}
77
78impl<T> StringIterable for Option<Vec<T>>
79where
80    T: Display,
81{
82    fn to_string_vec(&self) -> Vec<String> {
83        self.iter()
84            .flat_map(|v| v.iter().map(ToString::to_string))
85            .collect()
86    }
87}
88
89impl<T> StringIterable for [T]
90where
91    T: Display,
92{
93    fn to_string_vec(&self) -> Vec<String> {
94        self.iter().map(ToString::to_string).collect()
95    }
96}
97
98impl<T> StringIterable for Vec<T>
99where
100    T: Display,
101{
102    fn to_string_vec(&self) -> Vec<String> {
103        self.iter().map(ToString::to_string).collect()
104    }
105}
106
107#[cfg(test)]
108mod tests {
109    use super::*;
110
111    #[test]
112    fn test_into_ref_vec() {
113        let v = vec![1, 2, 3, 4, 5];
114        assert_eq!(v.as_ref_vec(), vec![&1, &2, &3, &4, &5]);
115
116        let v2 = Some(v);
117        assert_eq!(v2.as_ref_vec(), vec![&1, &2, &3, &4, &5]);
118
119        let mut v3 = vec![1, 2, 3, 4, 5];
120        assert_eq!(
121            v3.as_mut_ref_vec(),
122            vec![&mut 1, &mut 2, &mut 3, &mut 4, &mut 5]
123        );
124
125        let mut v4 = Some(v3);
126        assert_eq!(
127            v4.as_mut_ref_vec(),
128            vec![&mut 1, &mut 2, &mut 3, &mut 4, &mut 5]
129        );
130    }
131
132    #[test]
133    fn test_string_iterable() {
134        let v = vec![1, 2, 3, 4, 5];
135        assert_eq!(v.to_string_vec(), vec!["1", "2", "3", "4", "5"]);
136
137        let v2 = [1, 2, 3, 4, 5];
138        assert_eq!(v2.to_string_vec(), vec!["1", "2", "3", "4", "5"]);
139
140        let v3 = Some(v);
141        assert_eq!(v3.to_string_vec(), vec!["1", "2", "3", "4", "5"]);
142
143        let v4: Option<Vec<i32>> = None;
144        assert_eq!(v4.to_string_vec(), Vec::<String>::new());
145    }
146}