valuable/slice.rs
1use crate::*;
2
3use core::fmt;
4use core::iter::FusedIterator;
5
6macro_rules! slice {
7 (
8 $(
9 $(#[$attrs:meta])*
10 $variant:ident($ty:ty),
11 )*
12 ) => {
13 /// A slice containing primitive values.
14 ///
15 /// The `Slice` enum is used to pass multiple primitive-values to the
16 /// [visitor][`Visit`]. This is used as an optimization when visiting
17 /// [`Listable`] types to avoid a dynamic dispatch call to [`Visit`] for
18 /// each element in the collection.
19 ///
20 /// `Slice` instances are usually not created explicitly. Instead, they
21 /// are created when calling [`Valuable::visit_slice()`].
22 #[non_exhaustive]
23 pub enum Slice<'a> {
24 $(
25 $(#[$attrs])*
26 $variant(&'a [$ty]),
27 )*
28 }
29
30 /// [`Slice`] iterator
31 ///
32 /// Instances are created by the [`iter()`][Slice::iter] method on
33 /// [`Slice`]. See its documentation for more.
34 ///
35 /// # Examples
36 ///
37 /// ```
38 /// use valuable::Slice;
39 ///
40 /// let slice = Slice::U32(&[1, 1, 2, 3, 5]);
41 ///
42 /// for value in slice.iter() {
43 /// println!("{:?}", value);
44 /// }
45 /// ```
46 #[derive(Debug)]
47 pub struct Iter<'a>(IterKind<'a>);
48
49 #[derive(Debug)]
50 enum IterKind<'a> {
51 $(
52 $(#[$attrs])*
53 $variant(core::slice::Iter<'a, $ty>),
54 )*
55 }
56
57 impl<'a> Slice<'a> {
58 /// Returns the number of elements in the slice
59 ///
60 /// # Examples
61 ///
62 /// ```
63 /// use valuable::Slice;
64 ///
65 /// let slice = Slice::U32(&[1, 1, 2, 3, 5]);
66 /// assert_eq!(5, slice.len());
67 /// ```
68 pub fn len(&self) -> usize {
69 #[allow(unused_doc_comments)]
70 match self {
71 $(
72 $(#[$attrs])*
73 Slice::$variant(s) => s.len(),
74 )*
75 }
76 }
77
78
79 /// Returns `true` if the slice is not empty.
80 ///
81 /// # Examples
82 ///
83 /// ```
84 /// use valuable::Slice;
85 ///
86 /// let slice = Slice::U32(&[1, 1, 2, 3, 5]);
87 /// assert!(!slice.is_empty());
88 /// ```
89 /// ```
90 /// # use valuable::Slice;
91 /// let slice = Slice::U32(&[]);
92 /// assert!(slice.is_empty());
93 /// ```
94 pub fn is_empty(&self) -> bool {
95 self.len() == 0
96 }
97
98 /// Returns an iterator over the slice.
99 ///
100 /// # Examples
101 ///
102 /// ```
103 /// use valuable::Slice;
104 ///
105 /// let slice = Slice::U32(&[1, 1, 2, 3, 5]);
106 ///
107 /// for value in slice.iter() {
108 /// println!("{:?}", value);
109 /// }
110 /// ```
111 pub fn iter(&self) -> Iter<'a> {
112 self.into_iter()
113 }
114 }
115
116 impl<'a> IntoIterator for Slice<'a> {
117 type Item = Value<'a>;
118 type IntoIter = Iter<'a>;
119
120 fn into_iter(self) -> Self::IntoIter {
121 (&self).into_iter()
122 }
123 }
124
125 impl<'a> IntoIterator for &'_ Slice<'a> {
126 type Item = Value<'a>;
127 type IntoIter = Iter<'a>;
128
129 fn into_iter(self) -> Self::IntoIter {
130 #[allow(unused_doc_comments)]
131 Iter(match self {
132 $(
133 $(#[$attrs])*
134 Slice::$variant(s) => IterKind::$variant(s.iter()),
135 )*
136 })
137 }
138 }
139
140 impl fmt::Debug for Slice<'_> {
141 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
142 use Slice::*;
143
144 let mut d = fmt.debug_list();
145
146 #[allow(unused_doc_comments)]
147 match *self {
148 $(
149 $(#[$attrs])*
150 $variant(v) => d.entries(v),
151 )*
152 };
153
154 d.finish()
155 }
156 }
157
158 impl<'a> Iterator for Iter<'a> {
159 type Item = Value<'a>;
160
161 fn size_hint(&self) -> (usize, Option<usize>) {
162 use IterKind::*;
163
164 #[allow(unused_doc_comments)]
165 match &self.0 {
166 $(
167 $(#[$attrs])*
168 $variant(v) => v.size_hint(),
169 )*
170 }
171 }
172
173 fn next(&mut self) -> Option<Value<'a>> {
174 use IterKind::*;
175
176 #[allow(unused_doc_comments)]
177 match &mut self.0 {
178 $(
179 $(#[$attrs])*
180 $variant(v) => v.next().map(Valuable::as_value),
181 )*
182 }
183 }
184 }
185
186 impl DoubleEndedIterator for Iter<'_> {
187 fn next_back(&mut self) -> Option<Self::Item> {
188 use IterKind::*;
189
190 #[allow(unused_doc_comments)]
191 match &mut self.0 {
192 $(
193 $(#[$attrs])*
194 $variant(v) => v.next_back().map(Valuable::as_value),
195 )*
196 }
197 }
198 }
199
200 impl ExactSizeIterator for Iter<'_> {
201 fn len(&self) -> usize {
202 use IterKind::*;
203
204 #[allow(unused_doc_comments)]
205 match &self.0 {
206 $(
207 $(#[$attrs])*
208 $variant(v) => v.len(),
209 )*
210 }
211 }
212 }
213
214 impl FusedIterator for Iter<'_> {}
215 }
216}
217
218slice! {
219 /// A slice containing `bool` values.
220 ///
221 /// # Examples
222 ///
223 /// ```
224 /// use valuable::Slice;
225 ///
226 /// let v = Slice::Bool(&[true, true, false]);
227 /// ```
228 Bool(bool),
229
230 /// A slice containing `char` values.
231 ///
232 /// # Examples
233 ///
234 /// ```
235 /// use valuable::Slice;
236 ///
237 /// let v = Slice::Char(&['a', 'b', 'c']);
238 /// ```
239 Char(char),
240
241 /// A slice containing `f32` values.
242 ///
243 /// # Examples
244 ///
245 /// ```
246 /// use valuable::Slice;
247 ///
248 /// let v = Slice::F32(&[3.1415, 2.71828]);
249 /// ```
250 F32(f32),
251
252 /// A slice containing `f64` values.
253 ///
254 /// # Examples
255 ///
256 /// ```
257 /// use valuable::Slice;
258 ///
259 /// let v = Slice::F64(&[3.1415, 2.71828]);
260 /// ```
261 F64(f64),
262
263 /// A slice containing `i8` values.
264 ///
265 /// # Examples
266 ///
267 /// ```
268 /// use valuable::Slice;
269 ///
270 /// let v = Slice::I8(&[1, 1, 2, 3, 5]);
271 /// ```
272 I8(i8),
273
274 /// A slice containing `i16` values.
275 ///
276 /// # Examples
277 ///
278 /// ```
279 /// use valuable::Slice;
280 ///
281 /// let v = Slice::I16(&[1, 1, 2, 3, 5]);
282 /// ```
283 I16(i16),
284
285 /// A slice containing `I32` values.
286 ///
287 /// # Examples
288 ///
289 /// ```
290 /// use valuable::Slice;
291 ///
292 /// let v = Slice::I32(&[1, 1, 2, 3, 5]);
293 /// ```
294 I32(i32),
295
296 /// A slice containing `I64` values.
297 ///
298 /// # Examples
299 ///
300 /// ```
301 /// use valuable::Slice;
302 ///
303 /// let v = Slice::I64(&[1, 1, 2, 3, 5]);
304 /// ```
305 I64(i64),
306
307 /// A slice containing `I128` values.
308 ///
309 /// # Examples
310 ///
311 /// ```
312 /// use valuable::Slice;
313 ///
314 /// let v = Slice::I128(&[1, 1, 2, 3, 5]);
315 /// ```
316 I128(i128),
317
318 /// A slice containing `isize` values.
319 ///
320 /// # Examples
321 ///
322 /// ```
323 /// use valuable::Slice;
324 ///
325 /// let v = Slice::Isize(&[1, 1, 2, 3, 5]);
326 /// ```
327 Isize(isize),
328
329 /// A slice containing `str` values.
330 ///
331 /// # Examples
332 ///
333 /// ```
334 /// use valuable::Slice;
335 ///
336 /// let v = Slice::Str(&["foo", "bar", "baz"]);
337 /// ```
338 Str(&'a str),
339
340 /// A slice containing `String` values.
341 ///
342 /// # Examples
343 ///
344 /// ```
345 /// use valuable::Slice;
346 ///
347 /// let v = Slice::String(&["foo".to_string(), "bar".to_string()]);
348 /// ```
349 #[cfg(feature = "alloc")]
350 String(alloc::string::String),
351
352 /// A slice containing `u8` values.
353 ///
354 /// # Examples
355 ///
356 /// ```
357 /// use valuable::Slice;
358 ///
359 /// let v = Slice::U8(&[1, 1, 2, 3, 5]);
360 /// ```
361 U8(u8),
362
363 /// A slice containing `u16` values.
364 ///
365 /// # Examples
366 ///
367 /// ```
368 /// use valuable::Slice;
369 ///
370 /// let v = Slice::U16(&[1, 1, 2, 3, 5]);
371 /// ```
372 U16(u16),
373
374 /// A slice containing `u32` values.
375 ///
376 /// # Examples
377 ///
378 /// ```
379 /// use valuable::Slice;
380 ///
381 /// let v = Slice::U32(&[1, 1, 2, 3, 5]);
382 /// ```
383 U32(u32),
384
385 /// A slice containing `u64` values.
386 ///
387 /// # Examples
388 ///
389 /// ```
390 /// use valuable::Slice;
391 ///
392 /// let v = Slice::U64(&[1, 1, 2, 3, 5]);
393 /// ```
394 U64(u64),
395
396 /// A slice containing `u128` values.
397 ///
398 /// # Examples
399 ///
400 /// ```
401 /// use valuable::Slice;
402 ///
403 /// let v = Slice::U128(&[1, 1, 2, 3, 5]);
404 /// ```
405 U128(u128),
406
407 /// A slice containing `usize` values.
408 ///
409 /// # Examples
410 ///
411 /// ```
412 /// use valuable::Slice;
413 ///
414 /// let v = Slice::Usize(&[1, 1, 2, 3, 5]);
415 /// ```
416 Usize(usize),
417
418 /// A slice containing `()` values.
419 ///
420 /// # Examples
421 ///
422 /// ```
423 /// use valuable::Slice;
424 ///
425 /// let v = Slice::Unit(&[(), (), ()]);
426 /// ```
427 Unit(()),
428}