1use std::{
4 collections::{BTreeMap, BTreeSet, HashMap, HashSet},
5 hash::{BuildHasher, Hash},
6 iter, mem,
7 ops::{Deref, DerefMut},
8};
9
10pub fn if_empty<V, C, Parser, Input>(
31 parse: Parser,
32) -> impl FnOnce(&mut C, Input) -> syn::Result<()>
33where
34 C: Container<V> + ?Sized,
35 Parser: FnOnce(Input) -> syn::Result<Option<V>>,
36{
37 move |container, input| {
38 if container.is_empty() {
39 if let Some(val) = parse(input)? {
40 container.set(val);
41 }
42 }
43 Ok(())
44 }
45}
46
47pub trait Container<V> {
49 type Value;
51
52 #[must_use]
54 fn is_empty(&self) -> bool;
55
56 #[must_use]
58 fn has(&self, value: &V) -> bool;
59
60 fn replace(&mut self, value: V) -> Option<V>;
63
64 fn set(&mut self, value: V) {
67 drop(self.replace(value));
68 }
69}
70
71impl<V> Container<V> for Option<V> {
72 type Value = V;
73
74 fn is_empty(&self) -> bool {
75 self.is_none()
76 }
77
78 fn has(&self, _: &V) -> bool {
79 self.is_some()
80 }
81
82 fn replace(&mut self, val: V) -> Self {
83 Self::replace(self, val)
84 }
85}
86
87impl<V> Container<V> for Required<V> {
88 type Value = V;
89
90 fn is_empty(&self) -> bool {
91 !self.is_present()
92 }
93
94 fn has(&self, _: &V) -> bool {
95 self.is_present()
96 }
97
98 fn replace(&mut self, val: V) -> Option<V> {
99 Self::replace_with(self, val)
100 }
101}
102
103impl<V: PartialEq> Container<V> for Vec<V> {
104 type Value = V;
105
106 fn is_empty(&self) -> bool {
107 Self::is_empty(self)
108 }
109
110 fn has(&self, val: &V) -> bool {
111 self.contains(val)
112 }
113
114 fn replace(&mut self, val: V) -> Option<V> {
115 if let Some(old) = self.iter_mut().find(|v| *v == &val) {
116 Some(mem::replace(old, val))
117 } else {
118 self.push(val);
119 None
120 }
121 }
122}
123
124impl<V, S> Container<V> for HashSet<V, S>
125where
126 V: Eq + Hash,
127 S: BuildHasher,
128{
129 type Value = V;
130
131 fn is_empty(&self) -> bool {
132 Self::is_empty(self)
133 }
134
135 fn has(&self, val: &V) -> bool {
136 self.contains(val)
137 }
138
139 fn replace(&mut self, val: V) -> Option<V> {
140 Self::replace(self, val)
141 }
142}
143
144impl<V: Ord> Container<V> for BTreeSet<V> {
145 type Value = V;
146
147 fn is_empty(&self) -> bool {
148 Self::is_empty(self)
149 }
150
151 fn has(&self, val: &V) -> bool {
152 self.contains(val)
153 }
154
155 fn replace(&mut self, val: V) -> Option<V> {
156 Self::replace(self, val)
157 }
158}
159
160impl<K, V, S> Container<(K, V)> for HashMap<K, V, S>
161where
162 K: Eq + Hash,
163 S: BuildHasher,
164{
165 type Value = (K, V);
166
167 fn is_empty(&self) -> bool {
168 Self::is_empty(self)
169 }
170
171 fn has(&self, val: &(K, V)) -> bool {
172 self.contains_key(&val.0)
173 }
174
175 fn replace(&mut self, val: (K, V)) -> Option<(K, V)> {
176 let prev = self.remove_entry(&val.0);
177 drop(self.insert(val.0, val.1));
178 prev
179 }
180}
181
182impl<K: Ord, V> Container<(K, V)> for BTreeMap<K, V> {
183 type Value = (K, V);
184
185 fn is_empty(&self) -> bool {
186 Self::is_empty(self)
187 }
188
189 fn has(&self, val: &(K, V)) -> bool {
190 self.contains_key(&val.0)
191 }
192
193 fn replace(&mut self, val: (K, V)) -> Option<(K, V)> {
194 let prev = self.remove_entry(&val.0);
195 drop(self.insert(val.0, val.1));
196 prev
197 }
198}
199
200#[derive(Clone, Copy, Debug)]
211pub struct Required<T>(Option<T>);
212
213#[doc(hidden)]
214impl<T> Default for Required<T> {
215 fn default() -> Self {
216 Self(None)
217 }
218}
219
220impl<T> Required<T> {
221 #[must_use]
224 pub(crate) const fn is_present(&self) -> bool {
225 self.0.is_some()
226 }
227
228 #[must_use]
231 pub(crate) fn replace_with(&mut self, value: T) -> Option<T> {
232 self.0.replace(value)
233 }
234
235 #[must_use]
238 pub(crate) fn take(&mut self) -> Option<T> {
239 self.0.take()
240 }
241
242 #[must_use]
249 pub fn into_inner(self) -> T {
250 #[allow(clippy::expect_used)]
251 self.0.expect("Uninitialized `Required` value")
252 }
253}
254
255impl<T> Deref for Required<T> {
256 type Target = T;
257
258 fn deref(&self) -> &Self::Target {
259 #[allow(clippy::expect_used)]
260 self.0.as_ref().expect("Uninitialized `Required` value")
261 }
262}
263
264impl<T> DerefMut for Required<T> {
265 fn deref_mut(&mut self) -> &mut Self::Target {
266 #[allow(clippy::expect_used)]
267 self.0.as_mut().expect("Uninitialized `Required` value")
268 }
269}
270
271impl<T> IntoIterator for Required<T> {
272 type Item = T;
273 type IntoIter = iter::Once<T>;
274
275 fn into_iter(self) -> Self::IntoIter {
276 iter::once(self.into_inner())
277 }
278}
279
280impl<'a, T> IntoIterator for &'a Required<T> {
281 type Item = &'a T;
282 type IntoIter = iter::Once<&'a T>;
283
284 fn into_iter(self) -> Self::IntoIter {
285 iter::once(&**self)
286 }
287}
288
289impl<'a, T> IntoIterator for &'a mut Required<T> {
290 type Item = &'a mut T;
291 type IntoIter = iter::Once<&'a mut T>;
292
293 fn into_iter(self) -> Self::IntoIter {
294 iter::once(&mut *self)
295 }
296}