fera_ext/
vec.rs

1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at http://mozilla.org/MPL/2.0/.
4
5//! An extension trait for `std::vec::Vec`.
6
7use rand::prelude::*;
8
9use std::cmp::Ordering;
10
11/// An extension trait for [`std::vec::Vec`].
12///
13/// Methods with the suffix `ed` are like the original methods, but consumes the vector. This is
14/// interesting to chain methods call. For example:
15///
16/// ```
17/// use fera_ext::VecExt;
18///
19/// assert_eq!(vec![1, 2, 3], vec![4, 3, 1, 3, 4, 2].sorted().deduped().truncated(3));
20/// ```
21///
22/// [`std::vec::Vec`]: https://doc.rust-lang.org/stable/std/vec/struct.Vec.html
23// TODO: create a plugin to generated *ed methods
24#[allow(missing_docs)]
25pub trait VecExt<T> {
26    /// Creates a new vector with `len` uninitialized elements.
27    ///
28    /// # Safety
29    ///
30    /// This is unsafe because some values may not be dropped or some values may be dropped
31    /// without being initialized. See [`std::mem::uninitialized`] for more informations.
32    ///
33    /// [`std::mem::uninitialized`]: https://doc.rust-lang.org/stable/std/mem/fn.uninitialized.html
34    unsafe fn new_uninitialized(len: usize) -> Self;
35
36    fn appended(self, other: &mut Self) -> Self;
37
38    fn deduped(self) -> Self
39    where
40        T: PartialEq;
41
42    fn deduped_by<F>(self, same_bucket: F) -> Self
43    where
44        F: FnMut(&mut T, &mut T) -> bool;
45
46    fn deduped_by_key<F, K>(self, key: F) -> Self
47    where
48        F: FnMut(&mut T) -> K,
49        K: PartialEq<K>;
50
51    fn resized(self, new_len: usize, value: T) -> Self
52    where
53        T: Clone;
54
55    fn reversed(self) -> Self;
56
57    fn shrinked_to_fit(self) -> Self;
58
59    /// Shuffle this vector using `SmallRng::from_entropy()`.
60    fn shuffled(self) -> Self;
61
62    /// Shuffle this vector using `rng`.
63    fn shuffled_with<R: Rng>(self, rng: R) -> Self;
64
65    fn sorted(self) -> Self
66    where
67        T: Ord;
68
69    fn sorted_by<F>(self, compare: F) -> Self
70    where
71        F: FnMut(&T, &T) -> Ordering;
72
73    fn sorted_by_key<F, K>(self, key: F) -> Self
74    where
75        F: FnMut(&T) -> K,
76        K: Ord;
77
78    fn truncated(self, len: usize) -> Self;
79}
80
81impl<T> VecExt<T> for Vec<T> {
82    unsafe fn new_uninitialized(size: usize) -> Self {
83        let mut v = Vec::with_capacity(size);
84        v.set_len(size);
85        v
86    }
87
88    fn deduped(mut self) -> Self
89    where
90        T: PartialEq,
91    {
92        self.dedup();
93        self
94    }
95
96    fn deduped_by<F>(mut self, same_bucket: F) -> Self
97    where
98        F: FnMut(&mut T, &mut T) -> bool,
99    {
100        self.dedup_by(same_bucket);
101        self
102    }
103
104    fn deduped_by_key<F, K>(mut self, key: F) -> Self
105    where
106        F: FnMut(&mut T) -> K,
107        K: PartialEq<K>,
108    {
109        self.dedup_by_key(key);
110        self
111    }
112
113    fn appended(mut self, other: &mut Self) -> Self {
114        self.append(other);
115        self
116    }
117
118    fn resized(mut self, new_len: usize, value: T) -> Self
119    where
120        T: Clone,
121    {
122        self.resize(new_len, value);
123        self
124    }
125
126    fn reversed(mut self) -> Self {
127        self.reverse();
128        self
129    }
130
131    fn shrinked_to_fit(mut self) -> Self {
132        self.shrink_to_fit();
133        self
134    }
135
136    fn shuffled(self) -> Self {
137        self.shuffled_with(SmallRng::from_entropy())
138    }
139
140    fn shuffled_with<R: Rng>(mut self, mut rng: R) -> Self {
141        rng.shuffle(&mut self[..]);
142        self
143    }
144
145    fn sorted(mut self) -> Self
146    where
147        T: Ord,
148    {
149        self.sort();
150        self
151    }
152
153    fn sorted_by<F>(mut self, compare: F) -> Self
154    where
155        F: FnMut(&T, &T) -> Ordering,
156    {
157        self.sort_by(compare);
158        self
159    }
160
161    fn sorted_by_key<F, K>(mut self, key: F) -> Self
162    where
163        F: FnMut(&T) -> K,
164        K: Ord,
165    {
166        self.sort_by_key(key);
167        self
168    }
169
170    fn truncated(mut self, len: usize) -> Self {
171        self.truncate(len);
172        self
173    }
174}
175
176#[cfg(test)]
177mod tests {
178    use super::*;
179
180    #[test]
181    fn test_deduped() {
182        assert_eq!(vec![1, 2, 3, 1], vec![1, 1, 2, 3, 3, 1].deduped());
183    }
184
185    #[test]
186    fn test_appended() {
187        assert_eq!(vec![1, 2, 3, 4, 5], vec![1, 2].appended(&mut vec![3, 4, 5]));
188    }
189
190    #[test]
191    fn test_resized() {
192        assert_eq!(vec![3, 4, 1, 1, 1], vec![3, 4, 1].resized(5, 1));
193        assert_eq!(vec![3, 4], vec![3, 4, 1].resized(2, 1));
194    }
195
196    #[test]
197    fn test_reversed() {
198        assert_eq!(vec![3, 2, 1], vec![1, 2, 3].reversed());
199    }
200
201    #[test]
202    fn test_sorted() {
203        assert_eq!(vec![1, 2, 3], vec![3, 1, 2].sorted());
204    }
205
206    #[test]
207    fn test_sorted_by() {
208        assert_eq!(vec![3, 2, 1], vec![1, 2, 3].sorted_by(|a, b| b.cmp(a)));
209    }
210
211    #[test]
212    fn test_sorted_by_key() {
213        assert_eq!(
214            vec![1isize, 2, -3],
215            vec![-3isize, 2, 1].sorted_by_key(|a| a.abs())
216        );
217    }
218
219    #[test]
220    fn test_shuffled() {
221        let v = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
222        let s = v.clone().shuffled();
223        assert!(v != s);
224        assert_eq!(v, s.sorted());
225    }
226
227    #[test]
228    fn test_truncated() {
229        assert_eq!(vec![1, 2], vec![1, 2, 3, 4].truncated(2));
230    }
231}