facet_reflect/peek/
list.rs

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