mithril_client/utils/
vec_deque_extensions.rs

1use std::collections::VecDeque;
2
3pub trait VecDequeExtensions<T> {
4    /// Removes the first `n` elements from the vector and returns them as a new vector.
5    ///
6    /// If `n` is greater than the length of the vector, the whole vector is drained.
7    fn pop_up_to_n(&mut self, n: usize) -> VecDeque<T>;
8}
9
10impl<T> VecDequeExtensions<T> for VecDeque<T> {
11    fn pop_up_to_n(&mut self, n: usize) -> VecDeque<T> {
12        let num_elements_to_pop = if n <= self.len() { n } else { self.len() };
13        self.drain(..num_elements_to_pop).collect()
14    }
15}
16
17#[cfg(test)]
18mod tests {
19    use super::*;
20
21    #[test]
22    fn pop_zero_element_return_empty_vec() {
23        let mut vec = VecDeque::from([1, 2, 3]);
24        let popped = vec.pop_up_to_n(0);
25
26        assert_eq!(popped, Vec::<i32>::new());
27        assert_eq!(vec, vec![1, 2, 3]);
28    }
29
30    #[test]
31    fn pop_one_element_return_vec_with_the_first_element() {
32        let mut vec = VecDeque::from([1, 2, 3]);
33        let popped = vec.pop_up_to_n(1);
34
35        assert_eq!(popped, vec![1]);
36        assert_eq!(vec, vec![2, 3]);
37    }
38
39    #[test]
40    fn pop_all_elements_leave_source_vec_empty() {
41        let mut vec = VecDeque::from([1, 2, 3]);
42        let popped = vec.pop_up_to_n(vec.len());
43
44        assert_eq!(popped, vec![1, 2, 3]);
45        assert_eq!(vec, Vec::<i32>::new());
46    }
47
48    #[test]
49    fn pop_more_than_source_vec_size_is_equivalent_to_popping_all_elements() {
50        let mut vec = VecDeque::from([1, 2, 3]);
51        let popped = vec.pop_up_to_n(vec.len() + 1);
52
53        assert_eq!(popped, vec![1, 2, 3]);
54        assert_eq!(vec, Vec::<i32>::new());
55    }
56}