1use std::marker::PhantomData;
19
20use super::Unpacker;
21
22pub trait View<'a>: Sized {
25 type View;
26 type ListView;
27 fn unpack_view(u: &mut Unpacker<'a>) -> Option<Self::View>;
28 fn unpack_list_view(u: &mut Unpacker<'a>) -> Option<Self::ListView>;
29}
30
31pub fn read_view<'a, T: View<'a>>(bytes: &'a [u8]) -> Option<T::View> {
33 let mut u = Unpacker::open(bytes)?;
34 let v = T::unpack_view(&mut u)?;
35 u.at_end().then_some(v)
36}
37
38pub struct List<'a, T> {
41 u: Unpacker<'a>,
42 len: usize,
43 item: PhantomData<fn() -> T>,
44}
45
46impl<'a, T> Clone for List<'a, T> {
47 fn clone(&self) -> Self {
48 List {
49 u: self.u.fork(self.u.position()),
50 len: self.len,
51 item: PhantomData,
52 }
53 }
54}
55
56impl<T> std::fmt::Debug for List<'_, T> {
57 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
58 write!(f, "List({} items)", self.len)
59 }
60}
61
62impl<'a, T: View<'a>> List<'a, T> {
63 pub fn len(&self) -> usize {
64 self.len
65 }
66
67 pub fn is_empty(&self) -> bool {
68 self.len == 0
69 }
70
71 pub fn iter(&self) -> ListIter<'a, T> {
73 ListIter {
74 u: self.u.fork(self.u.position()),
75 left: self.len,
76 item: PhantomData,
77 }
78 }
79
80 pub fn get(&self, i: usize) -> Option<T::View> {
82 self.iter().nth(i)
83 }
84}
85
86pub struct ListIter<'a, T> {
88 u: Unpacker<'a>,
89 left: usize,
90 item: PhantomData<fn() -> T>,
91}
92
93impl<'a, T: View<'a>> Iterator for ListIter<'a, T> {
94 type Item = T::View;
95 fn next(&mut self) -> Option<T::View> {
96 self.left = self.left.checked_sub(1)?;
97 T::unpack_view(&mut self.u)
98 }
99}
100
101pub fn list<'a, T: View<'a>>(u: &mut Unpacker<'a>) -> Option<List<'a, T>> {
103 let (len, end) = u.list()?;
104 let at = u.position();
105 u.skip_to(end)?;
106 Some(List {
107 u: u.fork(at),
108 len,
109 item: PhantomData,
110 })
111}
112
113impl<'a> View<'a> for bool {
114 type View = bool;
115 type ListView = List<'a, bool>;
116 fn unpack_view(u: &mut Unpacker<'a>) -> Option<bool> {
117 u.get_bool()
118 }
119 fn unpack_list_view(u: &mut Unpacker<'a>) -> Option<Self::ListView> {
120 list(u)
121 }
122}
123
124impl<'a> View<'a> for String {
125 type View = &'a str;
126 type ListView = List<'a, Self>;
127 fn unpack_view(u: &mut Unpacker<'a>) -> Option<&'a str> {
128 u.get_str()
129 }
130 fn unpack_list_view(u: &mut Unpacker<'a>) -> Option<Self::ListView> {
131 list(u)
132 }
133}
134
135impl<'a> View<'a> for Box<str> {
136 type View = &'a str;
137 type ListView = List<'a, Self>;
138 fn unpack_view(u: &mut Unpacker<'a>) -> Option<&'a str> {
139 u.get_str()
140 }
141 fn unpack_list_view(u: &mut Unpacker<'a>) -> Option<Self::ListView> {
142 list(u)
143 }
144}
145
146impl<'a> View<'a> for crate::Atom {
147 type View = crate::Atom;
148 type ListView = List<'a, crate::Atom>;
149 fn unpack_view(u: &mut Unpacker<'a>) -> Option<crate::Atom> {
150 <crate::Atom as crate::Schema>::unpack(u)
151 }
152 fn unpack_list_view(u: &mut Unpacker<'a>) -> Option<Self::ListView> {
153 list(u)
154 }
155}
156
157impl<'a, T: View<'a>> View<'a> for Option<T> {
158 type View = Option<T::View>;
159 type ListView = List<'a, Option<T>>;
160 fn unpack_view(u: &mut Unpacker<'a>) -> Option<Option<T::View>> {
161 if u.get_bool()? {
162 T::unpack_view(u).map(Some)
163 } else {
164 Some(None)
165 }
166 }
167 fn unpack_list_view(u: &mut Unpacker<'a>) -> Option<Self::ListView> {
168 list(u)
169 }
170}
171
172impl<'a, T: View<'a>> View<'a> for Box<T> {
173 type View = T::View;
174 type ListView = T::ListView;
175 fn unpack_view(u: &mut Unpacker<'a>) -> Option<T::View> {
176 T::unpack_view(u)
177 }
178 fn unpack_list_view(u: &mut Unpacker<'a>) -> Option<T::ListView> {
179 T::unpack_list_view(u)
180 }
181}
182
183impl<'a, T: View<'a>> View<'a> for Vec<T> {
184 type View = T::ListView;
185 type ListView = List<'a, Vec<T>>;
186 fn unpack_view(u: &mut Unpacker<'a>) -> Option<T::ListView> {
187 T::unpack_list_view(u)
188 }
189 fn unpack_list_view(u: &mut Unpacker<'a>) -> Option<Self::ListView> {
190 list(u)
191 }
192}
193
194#[derive(Debug, Clone, Copy)]
196pub struct Ints<'a, T> {
197 bytes: &'a [u8],
198 len: usize,
199 bits: u32,
200 signed: bool,
201 item: PhantomData<fn() -> T>,
202}
203
204impl<T: TryFrom<i128>> Ints<'_, T> {
205 pub fn len(&self) -> usize {
206 self.len
207 }
208
209 pub fn is_empty(&self) -> bool {
210 self.len == 0
211 }
212
213 pub fn get(&self, i: usize) -> Option<T> {
215 if i >= self.len {
216 return None;
217 }
218 let raw = super::lanes::get(self.bytes, self.len, self.bits, i);
219 let n = if self.signed {
220 i128::from(crate::binary::unzigzag(raw))
221 } else {
222 i128::from(raw)
223 };
224 T::try_from(n).ok()
225 }
226
227 pub fn iter(&self) -> impl Iterator<Item = T> + '_ {
228 (0..self.len).map_while(|i| self.get(i))
229 }
230}
231
232#[derive(Debug, Clone, Copy)]
234pub struct Floats<'a, T> {
235 bytes: &'a [u8],
236 len: usize,
237 narrow: bool,
239 item: PhantomData<fn() -> T>,
240}
241
242const F32_BYTES: usize = 4;
243const F64_BYTES: usize = 8;
244
245impl<T: From<f32> + FromF64> Floats<'_, T> {
246 pub fn len(&self) -> usize {
247 self.len
248 }
249
250 pub fn is_empty(&self) -> bool {
251 self.len == 0
252 }
253
254 pub fn get(&self, i: usize) -> Option<T> {
255 if i >= self.len {
256 return None;
257 }
258 if self.narrow {
259 let b = self.bytes.get(i * F32_BYTES..(i + 1) * F32_BYTES)?;
260 Some(T::from(f32::from_le_bytes(b.try_into().ok()?)))
261 } else {
262 let b = self.bytes.get(i * F64_BYTES..(i + 1) * F64_BYTES)?;
263 Some(T::from_f64(f64::from_le_bytes(b.try_into().ok()?)))
264 }
265 }
266
267 pub fn iter(&self) -> impl Iterator<Item = T> + '_ {
268 (0..self.len).map_while(|i| self.get(i))
269 }
270}
271
272pub trait FromF64 {
274 fn from_f64(f: f64) -> Self;
275}
276
277impl FromF64 for f64 {
278 fn from_f64(f: f64) -> Self {
279 f
280 }
281}
282
283impl FromF64 for f32 {
284 fn from_f64(f: f64) -> Self {
285 f as f32
286 }
287}
288
289macro_rules! int_views {
290 ($($t:ty => $signed:expr),*) => {$(
291 impl<'a> View<'a> for $t {
292 type View = $t;
293 type ListView = Ints<'a, $t>;
294 fn unpack_view(u: &mut Unpacker<'a>) -> Option<$t> {
295 <$t as crate::Schema>::unpack(u)
296 }
297 fn unpack_list_view(u: &mut Unpacker<'a>) -> Option<Ints<'a, $t>> {
298 let (len, bits, bytes) = u.packed_ints()?;
299 Some(Ints { bytes, len, bits, signed: $signed, item: PhantomData })
300 }
301 }
302 )*};
303}
304int_views!(i8 => true, i16 => true, i32 => true, i64 => true, u8 => false, u16 => false, u32 => false, u64 => false, usize => false);
305
306macro_rules! float_views {
307 ($($t:ty => $wide:expr),*) => {$(
308 impl<'a> View<'a> for $t {
309 type View = $t;
310 type ListView = Floats<'a, $t>;
311 fn unpack_view(u: &mut Unpacker<'a>) -> Option<$t> {
312 <$t as crate::Schema>::unpack(u)
313 }
314 fn unpack_list_view(u: &mut Unpacker<'a>) -> Option<Floats<'a, $t>> {
315 let (len, narrow, bytes) = u.packed_floats($wide)?;
316 Some(Floats { bytes, len, narrow, item: PhantomData })
317 }
318 }
319 )*};
320}
321float_views!(f32 => false, f64 => true);