facet_reflect/peek/
list.rs

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