1#[cfg(feature = "alloc")]
2use alloc::{
3 collections::{
4 BTreeMap,
5 BTreeSet,
6 BinaryHeap,
7 LinkedList,
8 TryReserveError,
9 VecDeque,
10 },
11 string::String,
12 vec::Vec,
13};
14use core::convert::Infallible;
15#[cfg(feature = "hashmap")]
16use core::hash::{
17 BuildHasher,
18 Hash,
19};
20#[cfg(feature = "hashmap")]
21use std::collections::{
22 HashMap,
23 HashSet,
24};
25
26#[cfg(feature = "smallvec")]
27use smallvec::{
28 CollectionAllocErr,
29 SmallVec,
30};
31
32pub trait TryPush {
35 type Item;
37 type Error;
39 type ItemView<'a>
41 where
42 Self: 'a;
43
44 fn try_push<'a>(&'a mut self, item: Self::Item) -> Result<Self::ItemView<'a>, Self::Error>;
46}
47
48#[cfg(feature = "alloc")]
49impl<Item> TryPush for Vec<Item> {
50 type Error = (Self::Item, TryReserveError);
51 type Item = Item;
52 type ItemView<'a> = &'a mut Self::Item
53 where
54 Self: 'a;
55
56 fn try_push<'a>(&'a mut self, item: Self::Item) -> Result<Self::ItemView<'a>, Self::Error> {
57 match self.try_reserve(1) {
58 Ok(_) => {
59 self.push(item);
60 Ok(self.last_mut().unwrap())
61 }
62 Err(e) => Err((item, e)),
63 }
64 }
65}
66
67#[cfg(feature = "alloc")]
68impl TryPush for String {
69 type Error = (Self::Item, TryReserveError);
70 type Item = char;
71 type ItemView<'a> = Self::Item;
72
73 fn try_push<'a>(&'a mut self, c: Self::Item) -> Result<Self::ItemView<'a>, Self::Error> {
74 match self.try_reserve(1) {
75 Ok(_) => {
76 self.push(c);
77 Ok(self.chars().next_back().unwrap())
78 }
79 Err(e) => Err((c, e)),
80 }
81 }
82}
83
84#[cfg(feature = "alloc")]
85impl<Item> TryPush for VecDeque<Item> {
86 type Error = (Self::Item, TryReserveError);
87 type Item = Item;
88 type ItemView<'a> = &'a mut Self::Item
89 where
90 Self: 'a;
91
92 fn try_push<'a>(&'a mut self, item: Self::Item) -> Result<Self::ItemView<'a>, Self::Error> {
93 match self.try_reserve(1) {
94 Ok(_) => {
95 self.push_back(item);
96 Ok(self.back_mut().unwrap())
97 }
98 Err(e) => Err((item, e)),
99 }
100 }
101}
102
103#[cfg(feature = "alloc")]
104impl<Key: Ord, Value> TryPush for BTreeMap<Key, Value> {
105 type Error = (Self::Item, TryReserveError);
106 type Item = (Key, Value);
107 type ItemView<'a> = Option<Value>
109 where
110 Self: 'a;
111
112 fn try_push<'a>(&'a mut self, item: Self::Item) -> Result<Self::ItemView<'a>, Self::Error> {
113 Ok(self.insert(item.0, item.1))
114 }
115}
116
117#[cfg(feature = "alloc")]
118impl<Item: Ord> TryPush for BinaryHeap<Item> {
119 type Error = (Self::Item, TryReserveError);
120 type Item = Item;
121 type ItemView<'a> = ()
123 where
124 Self: 'a;
125
126 fn try_push<'a>(&'a mut self, item: Self::Item) -> Result<Self::ItemView<'a>, Self::Error> {
127 match self.try_reserve(1) {
128 Ok(_) => {
129 self.push(item);
130 Ok(())
131 }
132 Err(e) => Err((item, e)),
133 }
134 }
135}
136
137#[cfg(feature = "hashmap")]
138impl<Key: Eq + Hash, Value, Seed: BuildHasher> TryPush for HashMap<Key, Value, Seed> {
139 type Error = (Self::Item, TryReserveError);
140 type Item = (Key, Value);
141 type ItemView<'a> = Option<Value>
143 where
144 Self: 'a;
145
146 fn try_push<'a>(&'a mut self, item: Self::Item) -> Result<Self::ItemView<'a>, Self::Error> {
147 Ok(self.insert(item.0, item.1))
148 }
149}
150
151#[cfg(feature = "hashmap")]
152impl<Item: Eq + Hash, Seed: BuildHasher> TryPush for HashSet<Item, Seed> {
153 type Error = (Self::Item, TryReserveError);
154 type Item = Item;
155 type ItemView<'a> = bool
157 where
158 Self: 'a;
159
160 fn try_push<'a>(&'a mut self, item: Self::Item) -> Result<Self::ItemView<'a>, Self::Error> {
161 Ok(self.insert(item))
162 }
163}
164
165#[cfg(feature = "alloc")]
166impl<Item: Ord> TryPush for BTreeSet<Item> {
167 type Error = (Self::Item, TryReserveError);
168 type Item = Item;
169 type ItemView<'a> = bool
171 where
172 Self: 'a;
173
174 fn try_push(&mut self, item: Self::Item) -> Result<Self::ItemView<'_>, Self::Error> {
175 Ok(self.insert(item))
176 }
177}
178
179#[cfg(feature = "alloc")]
180impl<Item> TryPush for LinkedList<Item> {
181 type Error = (Self::Item, TryReserveError);
182 type Item = Item;
183 type ItemView<'a> = &'a mut Self::Item
184 where
185 Self: 'a;
186
187 fn try_push<'a>(&'a mut self, item: Self::Item) -> Result<Self::ItemView<'a>, Self::Error> {
188 self.push_back(item);
189 Ok(self.back_mut().unwrap())
190 }
191}
192
193#[cfg(feature = "smallvec")]
194impl<Item, const N: usize> TryPush for SmallVec<[Item; N]> {
195 type Error = (Self::Item, CollectionAllocErr);
196 type Item = Item;
197 type ItemView<'a> = &'a mut Self::Item
198 where
199 Self: 'a;
200
201 fn try_push<'a>(&'a mut self, item: Self::Item) -> Result<Self::ItemView<'a>, Self::Error> {
202 match self.try_reserve(1) {
203 Ok(_) => {
204 self.push(item);
205 Ok(self.last_mut().unwrap())
206 }
207 Err(e) => Err((item, e)),
208 }
209 }
210}
211
212impl TryPush for () {
213 type Error = Infallible;
214 type Item = ();
215 type ItemView<'a> = ();
216
217 fn try_push(&mut self, _: Self::Item) -> Result<Self::ItemView<'_>, Self::Error> {
218 Ok(())
219 }
220}