facet_reflect/peek/
list.rs

1use crate::Peek;
2
3use super::PeekValue;
4use facet_core::ListDef;
5
6/// Iterator over a `PeekList`
7pub struct PeekListIter<'mem> {
8    list: PeekList<'mem>,
9    index: usize,
10    len: usize,
11}
12
13impl<'mem> Iterator for PeekListIter<'mem> {
14    type Item = Peek<'mem>;
15
16    fn next(&mut self) -> Option<Self::Item> {
17        if self.index >= self.len {
18            return None;
19        }
20        let item = self.list.item_at(self.index);
21        self.index += 1;
22        item
23    }
24
25    fn size_hint(&self) -> (usize, Option<usize>) {
26        let remaining = self.len.saturating_sub(self.index);
27        (remaining, Some(remaining))
28    }
29}
30
31impl ExactSizeIterator for PeekListIter<'_> {}
32
33impl<'mem> IntoIterator for &'mem PeekList<'mem> {
34    type Item = Peek<'mem>;
35    type IntoIter = PeekListIter<'mem>;
36
37    fn into_iter(self) -> Self::IntoIter {
38        self.iter()
39    }
40}
41
42/// Lets you read from a list (implements read-only [`facet_core::ListVTable`] proxies)
43#[derive(Clone, Copy)]
44pub struct PeekList<'mem> {
45    value: PeekValue<'mem>,
46    def: ListDef,
47}
48
49impl<'mem> core::ops::Deref for PeekList<'mem> {
50    type Target = PeekValue<'mem>;
51
52    #[inline(always)]
53    fn deref(&self) -> &Self::Target {
54        &self.value
55    }
56}
57
58impl<'mem> PeekList<'mem> {
59    /// Creates a new peek list
60    pub fn new(value: PeekValue<'mem>, def: ListDef) -> Self {
61        Self { value, def }
62    }
63
64    /// Get the length of the list
65    pub fn len(&self) -> usize {
66        unsafe { (self.def.vtable.len)(self.value.data()) }
67    }
68
69    /// Returns true if the list is empty
70    pub fn is_empty(&self) -> bool {
71        self.len() == 0
72    }
73
74    /// Get an item from the list at the specified index
75    ///
76    /// # Panics
77    ///
78    /// Panics if the index is out of bounds
79    pub fn item_at(&self, index: usize) -> Option<Peek<'mem>> {
80        if index >= self.len() {
81            return None;
82        }
83
84        let item_ptr = unsafe { (self.def.vtable.get_item_ptr)(self.value.data(), index) };
85        Some(unsafe { Peek::unchecked_new(item_ptr, self.def.t) })
86    }
87
88    /// Returns an iterator over the list
89    pub fn iter(self) -> PeekListIter<'mem> {
90        PeekListIter {
91            list: self,
92            index: 0,
93            len: self.len(),
94        }
95    }
96
97    /// Def getter
98    pub fn def(&self) -> ListDef {
99        self.def
100    }
101}