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}