facet_reflect/peek/
list.rs1use super::Peek;
2use core::{fmt::Debug, marker::PhantomData};
3use facet_core::{ListDef, PtrConst, PtrMut};
4
5pub struct PeekListIter<'mem, 'facet> {
7 state: PeekListIterState<'mem>,
8 index: usize,
9 len: usize,
10 def: ListDef,
11 _list: PhantomData<Peek<'mem, 'facet>>,
12}
13
14impl<'mem, 'facet> Iterator for PeekListIter<'mem, 'facet> {
15 type Item = Peek<'mem, 'facet>;
16
17 #[inline]
18 fn next(&mut self) -> Option<Self::Item> {
19 let item_ptr = match &self.state.kind {
20 PeekListIterStateKind::Ptr { data, stride } => {
21 if self.index >= self.len {
22 return None;
23 }
24
25 unsafe { data.field(stride * self.index) }
26 }
27 PeekListIterStateKind::Iter { iter } => unsafe {
28 (self.def.iter_vtable().unwrap().next)(*iter)?
29 },
30 };
31
32 self.index += 1;
35
36 Some(unsafe { Peek::unchecked_new(item_ptr, self.def.t()) })
37 }
38
39 #[inline]
40 fn size_hint(&self) -> (usize, Option<usize>) {
41 let remaining = self.len.saturating_sub(self.index);
42 (remaining, Some(remaining))
43 }
44}
45
46impl ExactSizeIterator for PeekListIter<'_, '_> {}
47
48impl Drop for PeekListIter<'_, '_> {
49 #[inline]
50 fn drop(&mut self) {
51 match &self.state.kind {
52 PeekListIterStateKind::Iter { iter } => unsafe {
53 (self.def.iter_vtable().unwrap().dealloc)(*iter)
54 },
55 PeekListIterStateKind::Ptr { .. } => {
56 }
58 }
59 }
60}
61
62impl<'mem, 'facet> IntoIterator for &'mem PeekList<'mem, 'facet> {
63 type Item = Peek<'mem, 'facet>;
64 type IntoIter = PeekListIter<'mem, 'facet>;
65
66 #[inline]
67 fn into_iter(self) -> Self::IntoIter {
68 self.iter()
69 }
70}
71
72struct PeekListIterState<'mem> {
73 kind: PeekListIterStateKind,
74 _phantom: PhantomData<&'mem ()>,
75}
76
77enum PeekListIterStateKind {
78 Ptr { data: PtrConst, stride: usize },
79 Iter { iter: PtrMut },
80}
81
82#[derive(Clone, Copy)]
84pub struct PeekList<'mem, 'facet> {
85 pub(crate) value: Peek<'mem, 'facet>,
86 pub(crate) def: ListDef,
87}
88
89impl Debug for PeekList<'_, '_> {
90 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
91 f.debug_struct("PeekList").finish_non_exhaustive()
92 }
93}
94
95impl<'mem, 'facet> PeekList<'mem, 'facet> {
96 #[inline]
98 pub fn new(value: Peek<'mem, 'facet>, def: ListDef) -> Self {
99 Self { value, def }
100 }
101
102 #[inline]
104 pub fn len(&self) -> usize {
105 unsafe { (self.def.vtable.len)(self.value.data()) }
106 }
107
108 #[inline]
110 pub fn is_empty(&self) -> bool {
111 self.len() == 0
112 }
113
114 #[inline]
116 pub fn get(&self, index: usize) -> Option<Peek<'mem, 'facet>> {
117 let item = unsafe { (self.def.vtable.get)(self.value.data(), index, self.value.shape())? };
118
119 Some(unsafe { Peek::unchecked_new(item, self.def.t()) })
120 }
121
122 pub fn iter(self) -> PeekListIter<'mem, 'facet> {
124 let state = if let Some(as_ptr_fn) = self.def.vtable.as_ptr {
125 let data = unsafe { as_ptr_fn(self.value.data()) };
126 let layout = self
127 .def
128 .t()
129 .layout
130 .sized_layout()
131 .expect("can only iterate over sized list elements");
132 let stride = layout.size();
133
134 PeekListIterState {
135 kind: PeekListIterStateKind::Ptr { data, stride },
136 _phantom: PhantomData,
137 }
138 } else {
139 let iter = unsafe {
140 (self.def.iter_vtable().unwrap().init_with_value.unwrap())(self.value.data())
141 };
142 PeekListIterState {
143 kind: PeekListIterStateKind::Iter { iter },
144 _phantom: PhantomData,
145 }
146 };
147
148 PeekListIter {
149 state,
150 index: 0,
151 len: self.len(),
152 def: self.def(),
153 _list: PhantomData,
154 }
155 }
156
157 #[inline]
159 pub fn def(&self) -> ListDef {
160 self.def
161 }
162}