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 value: Peek<'mem, 'facet>,
86 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]
108 pub const unsafe fn new(value: Peek<'mem, 'facet>, def: ListDef) -> Self {
109 Self { value, def }
110 }
111
112 #[inline]
114 pub fn len(&self) -> usize {
115 unsafe { (self.def.vtable.len)(self.value.data()) }
116 }
117
118 #[inline]
120 pub fn is_empty(&self) -> bool {
121 self.len() == 0
122 }
123
124 #[inline]
126 pub fn get(&self, index: usize) -> Option<Peek<'mem, 'facet>> {
127 let item = unsafe { (self.def.vtable.get)(self.value.data(), index, self.value.shape())? };
128
129 Some(unsafe { Peek::unchecked_new(item, self.def.t()) })
130 }
131
132 pub fn iter(self) -> PeekListIter<'mem, 'facet> {
134 let state = if let Some(as_ptr_fn) = self.def.vtable.as_ptr {
135 let data = unsafe { as_ptr_fn(self.value.data()) };
136 let layout = self
137 .def
138 .t()
139 .layout
140 .sized_layout()
141 .expect("can only iterate over sized list elements");
142 let stride = layout.size();
143
144 PeekListIterState {
145 kind: PeekListIterStateKind::Ptr { data, stride },
146 _phantom: PhantomData,
147 }
148 } else {
149 let iter = unsafe {
150 (self.def.iter_vtable().unwrap().init_with_value.unwrap())(self.value.data())
151 };
152 PeekListIterState {
153 kind: PeekListIterStateKind::Iter { iter },
154 _phantom: PhantomData,
155 }
156 };
157
158 PeekListIter {
159 state,
160 index: 0,
161 len: self.len(),
162 def: self.def(),
163 _list: PhantomData,
164 }
165 }
166
167 #[inline]
169 pub const fn def(&self) -> ListDef {
170 self.def
171 }
172}