facet_reflect/peek/
list_like.rs1use facet_core::{PtrConst, Shape};
2
3use super::Peek;
4use core::fmt::Debug;
5
6#[derive(Clone, Copy)]
8pub enum ListLikeDef {
9 List(facet_core::ListDef),
13
14 Array(facet_core::ArrayDef),
18
19 Slice(facet_core::SliceDef),
23}
24
25impl ListLikeDef {
26 pub fn t(&self) -> &'static Shape {
28 match self {
29 ListLikeDef::List(v) => v.t(),
30 ListLikeDef::Array(v) => v.t(),
31 ListLikeDef::Slice(v) => v.t(),
32 }
33 }
34}
35
36pub struct PeekListLikeIter<'mem, 'facet_lifetime> {
38 list: PeekListLike<'mem, 'facet_lifetime>,
39 index: usize,
40 len: usize,
41}
42
43impl<'mem, 'facet_lifetime> Iterator for PeekListLikeIter<'mem, 'facet_lifetime> {
44 type Item = Peek<'mem, 'facet_lifetime>;
45
46 fn next(&mut self) -> Option<Self::Item> {
47 if self.index >= self.len {
48 return None;
49 }
50 let item = self.list.get(self.index);
51 self.index += 1;
52 item
53 }
54
55 fn size_hint(&self) -> (usize, Option<usize>) {
56 let remaining = self.len.saturating_sub(self.index);
57 (remaining, Some(remaining))
58 }
59}
60
61impl ExactSizeIterator for PeekListLikeIter<'_, '_> {}
62
63impl<'mem, 'facet_lifetime> IntoIterator for &'mem PeekListLike<'mem, 'facet_lifetime> {
64 type Item = Peek<'mem, 'facet_lifetime>;
65 type IntoIter = PeekListLikeIter<'mem, 'facet_lifetime>;
66
67 fn into_iter(self) -> Self::IntoIter {
68 self.iter()
69 }
70}
71
72#[derive(Clone, Copy)]
74pub struct PeekListLike<'mem, 'facet_lifetime> {
75 pub(crate) value: Peek<'mem, 'facet_lifetime>,
76 pub(crate) def: ListLikeDef,
77 len: usize,
78 get_item_ptr: unsafe fn(array: PtrConst, index: usize) -> PtrConst,
79}
80
81impl Debug for PeekListLike<'_, '_> {
82 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
83 f.debug_struct("PeekListLike").finish_non_exhaustive()
84 }
85}
86
87impl<'mem, 'facet_lifetime> PeekListLike<'mem, 'facet_lifetime> {
88 pub fn new(value: Peek<'mem, 'facet_lifetime>, def: ListLikeDef) -> Self {
90 let (len, get_item_ptr) = match def {
91 ListLikeDef::List(v) => (
92 unsafe { (v.vtable.len)(value.data()) },
93 v.vtable.get_item_ptr,
94 ),
95 ListLikeDef::Slice(v) => (
96 unsafe { (v.vtable.len)(value.data()) },
97 v.vtable.get_item_ptr,
98 ),
99 ListLikeDef::Array(v) => (v.n, v.vtable.get_item_ptr),
100 };
101 Self {
102 value,
103 def,
104 len,
105 get_item_ptr,
106 }
107 }
108
109 pub fn len(&self) -> usize {
111 self.len
112 }
113
114 pub fn is_empty(&self) -> bool {
116 self.len() == 0
117 }
118
119 pub fn get(&self, index: usize) -> Option<Peek<'mem, 'facet_lifetime>> {
125 if index >= self.len() {
126 return None;
127 }
128
129 let item_ptr = unsafe { (self.get_item_ptr)(self.value.data(), index) };
130 Some(unsafe { Peek::unchecked_new(item_ptr, self.def.t()) })
131 }
132
133 pub fn iter(self) -> PeekListLikeIter<'mem, 'facet_lifetime> {
135 PeekListLikeIter {
136 list: self,
137 index: 0,
138 len: self.len(),
139 }
140 }
141
142 pub fn def(&self) -> ListLikeDef {
144 self.def
145 }
146}