std_ext/
vec.rs

1use std::ops::Deref;
2
3pub trait VecExt<T> {
4    fn any<F: Fn(&T) -> bool>(&self, f: F) -> bool;
5    fn fold<F, U>(&self, f: F, init: U) -> U
6    where
7        F: Fn(U, &T) -> U;
8    fn into_first(self) -> Option<T>;
9    fn into_last(self) -> Option<T>;
10    fn recollect<U: From<T>>(self) -> Vec<U>;
11}
12
13pub trait DerefVec<T>
14where
15    T: Deref,
16{
17    fn includes(&self, item: &T::Target) -> bool;
18}
19
20impl<T> VecExt<T> for Vec<T> {
21    fn any<F: Fn(&T) -> bool>(&self, f: F) -> bool {
22        self.iter().any(f)
23    }
24
25    fn fold<F, U>(&self, f: F, init: U) -> U
26    where
27        F: Fn(U, &T) -> U,
28    {
29        self.iter().fold(init, f)
30    }
31
32    fn into_first(self) -> Option<T> {
33        self.into_iter().next()
34    }
35
36    fn into_last(mut self) -> Option<T> {
37        if self.is_empty() {
38            return None;
39        }
40        Some(self.remove(self.len() - 1))
41    }
42    fn recollect<U: From<T>>(self) -> Vec<U> {
43        self.into_iter().map(Into::into).collect()
44    }
45}
46
47impl<T> DerefVec<T> for Vec<T>
48where
49    T: Deref + PartialEq<T::Target>,
50{
51    fn includes(&self, item: &T::Target) -> bool {
52        self.iter().any(|i| i == item)
53    }
54}
55
56#[macro_export]
57macro_rules! vec_into {
58    ($(($($item:expr),*)),* $(,)?) => {
59        {
60            let mut v = Vec::new();
61            $(v.push(($($item.into()),*));)*
62            v
63        }
64    };
65    ($($item:expr),* $(,)?) => {
66        {
67            let mut v = Vec::new();
68            $(v.push($item.into());)*
69            v
70        }
71    };
72}
73
74#[cfg(test)]
75mod tests {
76    use super::*;
77
78    #[test]
79    fn test_deref() {
80        let s = vec!["a".to_string(), "b".to_string()];
81        assert!(s.includes("a"));
82    }
83
84    #[test]
85    fn test_vec_into() {
86        let s: Vec<String> = vec_into!["a", "b"];
87        assert_eq!(s, vec!["a".to_string(), "b".to_string()]);
88    }
89}