facet_reflect/peek/
list.rs

1use super::Peek;
2use facet_core::ListDef;
3
4/// Iterator over a `PeekList`
5pub struct PeekListIter<'mem, 'facet_lifetime> {
6    list: PeekList<'mem, 'facet_lifetime>,
7    index: usize,
8    len: usize,
9}
10
11impl<'mem, 'facet_lifetime> Iterator for PeekListIter<'mem, 'facet_lifetime> {
12    type Item = Peek<'mem, 'facet_lifetime>;
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, 'facet_lifetime> IntoIterator for &'mem PeekList<'mem, 'facet_lifetime> {
32    type Item = Peek<'mem, 'facet_lifetime>;
33    type IntoIter = PeekListIter<'mem, 'facet_lifetime>;
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, 'facet_lifetime> {
43    pub(crate) value: Peek<'mem, 'facet_lifetime>,
44    pub(crate) def: ListDef,
45}
46
47impl<'mem, 'facet_lifetime> PeekList<'mem, 'facet_lifetime> {
48    /// Creates a new peek list
49    pub fn new(value: Peek<'mem, 'facet_lifetime>, 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, 'facet_lifetime>> {
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(unsafe { Peek::unchecked_new(item_ptr, self.def.t()) })
74    }
75
76    /// Returns an iterator over the list
77    pub fn iter(self) -> PeekListIter<'mem, 'facet_lifetime> {
78        PeekListIter {
79            list: self,
80            index: 0,
81            len: self.len(),
82        }
83    }
84
85    /// Def getter
86    pub fn def(&self) -> ListDef {
87        self.def
88    }
89}