binator/utils/
push.rs

1#[cfg(feature = "alloc")]
2use alloc::collections::{
3  BTreeMap,
4  BTreeSet,
5  BinaryHeap,
6  LinkedList,
7  VecDeque,
8};
9#[cfg(feature = "hashmap")]
10use core::hash::{
11  BuildHasher,
12  Hash,
13};
14#[cfg(feature = "hashmap")]
15use std::collections::{
16  HashMap,
17  HashSet,
18};
19
20#[cfg(feature = "smallvec")]
21use smallvec::SmallVec;
22
23/// Abstracts something which can push Item into self
24pub trait Push {
25  /// Item stocked in the collection
26  type Item;
27  /// Represent a way to access Item in the collection directly after push
28  type ItemView<'a>
29  where
30    Self: 'a;
31
32  /// push an item into a collection, no guarantee on ordering.
33  fn push<'a>(&'a mut self, item: Self::Item) -> Self::ItemView<'a>;
34}
35
36#[cfg(feature = "alloc")]
37impl<Item> Push for alloc::vec::Vec<Item> {
38  type Item = Item;
39  type ItemView<'a> = &'a mut Self::Item
40  where
41    Self: 'a;
42
43  #[allow(clippy::only_used_in_recursion)]
44  fn push<'a>(&'a mut self, item: Self::Item) -> Self::ItemView<'a> {
45    self.push(item);
46    self.last_mut().unwrap()
47  }
48}
49
50#[cfg(feature = "alloc")]
51impl Push for alloc::string::String {
52  type Item = char;
53  type ItemView<'a> = Self::Item;
54
55  fn push<'a>(&'a mut self, c: Self::Item) -> Self::ItemView<'a> {
56    self.push(c);
57    self.chars().next_back().unwrap()
58  }
59}
60
61#[cfg(feature = "alloc")]
62impl<Item> Push for VecDeque<Item> {
63  type Item = Item;
64  type ItemView<'a> = &'a mut Self::Item
65  where
66    Self: 'a;
67
68  fn push<'a>(&'a mut self, item: Self::Item) -> Self::ItemView<'a> {
69    self.push_back(item);
70    self.back_mut().unwrap()
71  }
72}
73
74#[cfg(feature = "alloc")]
75impl<Key: Ord, Value> Push for BTreeMap<Key, Value> {
76  type Item = (Key, Value);
77  // Not happy
78  type ItemView<'a> = Option<Value>
79  where
80    Self: 'a;
81
82  fn push<'a>(&'a mut self, item: Self::Item) -> Self::ItemView<'a> {
83    self.insert(item.0, item.1)
84  }
85}
86
87#[cfg(feature = "alloc")]
88impl<Item: Ord> Push for BinaryHeap<Item> {
89  type Item = Item;
90  // not happy
91  type ItemView<'a> = ()
92  where
93    Self: 'a;
94
95  fn push<'a>(&'a mut self, item: Self::Item) -> Self::ItemView<'a> {
96    self.push(item);
97  }
98}
99
100#[cfg(feature = "hashmap")]
101impl<Key: Eq + Hash, Value, Seed: BuildHasher> Push for HashMap<Key, Value, Seed> {
102  type Item = (Key, Value);
103  // Not happy
104  type ItemView<'a> = Option<Value>
105  where
106    Self: 'a;
107
108  fn push<'a>(&'a mut self, item: Self::Item) -> Self::ItemView<'a> {
109    self.insert(item.0, item.1)
110  }
111}
112
113#[cfg(feature = "hashmap")]
114impl<Item: Eq + Hash, Seed: BuildHasher> Push for HashSet<Item, Seed> {
115  type Item = Item;
116  // Not happy
117  type ItemView<'a> = bool
118  where
119    Self: 'a;
120
121  fn push<'a>(&'a mut self, item: Self::Item) -> Self::ItemView<'a> {
122    self.insert(item)
123  }
124}
125
126#[cfg(feature = "alloc")]
127impl<Item: Ord> Push for BTreeSet<Item> {
128  type Item = Item;
129  // Not happy
130  type ItemView<'a> = bool
131  where
132    Self: 'a;
133
134  fn push(&mut self, item: Self::Item) -> Self::ItemView<'_> {
135    self.insert(item)
136  }
137}
138
139#[cfg(feature = "alloc")]
140impl<Item> Push for LinkedList<Item> {
141  type Item = Item;
142  type ItemView<'a> = &'a mut Self::Item
143  where
144    Self: 'a;
145
146  fn push<'a>(&'a mut self, item: Self::Item) -> Self::ItemView<'a> {
147    self.push_back(item);
148    self.back_mut().unwrap()
149  }
150}
151
152#[cfg(feature = "smallvec")]
153impl<Item, const N: usize> Push for SmallVec<[Item; N]> {
154  type Item = Item;
155  type ItemView<'a> = &'a mut Self::Item
156  where
157    Self: 'a;
158
159  fn push<'a>(&'a mut self, item: Self::Item) -> Self::ItemView<'a> {
160    self.push(item);
161    self.last_mut().unwrap()
162  }
163}
164
165impl Push for () {
166  type Item = ();
167  type ItemView<'a> = ();
168
169  fn push(&mut self, _: Self::Item) -> Self::ItemView<'_> {}
170}