try_push/
lib.rs

1use std::collections::VecDeque;
2
3#[derive(Eq, PartialEq, Debug)]
4pub enum Element<T> {
5    Added,
6    NotAdded(T),
7}
8
9pub trait TryPush<T> {
10    /// Attempts to push an element to the collection. If that action would
11    /// re-allocate or require shifting elements then the `elem` is returned
12    /// in `Element::NotAdded()`. Otherwise, the return value is `Element::Added`.
13    fn try_push(&mut self, elem: T) -> Element<T>;
14
15    /// Attempts to push an element front to the collection. If that action would
16    /// re-allocate or require shifting elements then the `elem` is returned
17    /// in `Element::NotAdded()`. Otherwise, the return value is `Element::Added`.
18    fn try_push_front(&mut self, elem: T) -> Element<T>;
19}
20
21impl<T> TryPush<T> for Vec<T> {
22    fn try_push(&mut self, elem: T) -> Element<T> {
23        if self.capacity() == self.len() {
24            Element::NotAdded(elem)
25        } else {
26            self.push(elem);
27            Element::Added
28        }
29    }
30
31    fn try_push_front(&mut self, elem: T) -> Element<T> {
32        if self.capacity() == self.len() || self.len() > 0 {
33            Element::NotAdded(elem)
34        } else {
35            self.push(elem);
36            Element::Added
37        }
38    }
39}
40
41impl<T> TryPush<T> for VecDeque<T> {
42    fn try_push(&mut self, elem: T) -> Element<T> {
43        if self.capacity() == self.len() {
44            Element::NotAdded(elem)
45        } else {
46            self.push_back(elem);
47            Element::Added
48        }
49    }
50
51    fn try_push_front(&mut self, elem: T) -> Element<T> {
52        if self.capacity() == self.len() {
53            Element::NotAdded(elem)
54        } else {
55            self.push_front(elem);
56            Element::Added
57        }
58    }
59}
60
61#[cfg(test)]
62mod tests {
63    use super::*;
64
65    #[test]
66    fn should_not_add_to_empty_vec() {
67        assert_eq!(Vec::with_capacity(0).try_push(1), Element::NotAdded(1));
68    }
69
70    #[test]
71    fn should_add_to_capable_vec() {
72        assert_eq!(Vec::with_capacity(10).try_push(1), Element::Added);
73    }
74
75    #[test]
76    fn should_not_add_front_to_empty_vec() {
77        assert_eq!(Vec::with_capacity(0).try_push_front(1), Element::NotAdded(1));
78    }
79
80    #[test]
81    fn should_not_add_front_to_non_empty_vec() {
82        assert_eq!(vec![0, 1].try_push_front(1), Element::NotAdded(1));
83    }
84
85    #[test]
86    fn should_add_front_to_capable_vec() {
87        assert_eq!(Vec::with_capacity(10).try_push_front(1), Element::Added);
88    }
89
90    #[test]
91    fn should_not_add_to_empty_vec_deque() {
92        let mut vd = VecDeque::with_capacity(0);
93        vd.push_back(1);
94        assert_eq!(vd.try_push(1), Element::NotAdded(1));
95    }
96
97    #[test]
98    fn should_add_to_capable_vec_deque() {
99        assert_eq!(VecDeque::with_capacity(10).try_push(1), Element::Added);
100    }
101
102    #[test]
103    fn should_not_add_front_to_empty_vec_deque() {
104        let mut vd = VecDeque::with_capacity(0);
105        vd.push_back(1);
106        assert_eq!(vd.try_push_front(1), Element::NotAdded(1));
107    }
108
109    #[test]
110    fn should_add_front_to_capable_vec_deque() {
111        assert_eq!(VecDeque::with_capacity(10).try_push_front(1), Element::Added);
112    }
113}