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}