1#![allow(private_bounds)]
2
3use crate::prelude::*;
4
5pub use std::marker::PhantomData;
6
7#[derive(Copy, Clone, Default)]
9pub struct ZTArray<'a, T> {
10 _phantom: PhantomData<T>,
11 buf: &'a [u8],
12 len: usize,
13}
14
15impl<'a, T> ZTArray<'a, T> {
16 #[inline(always)]
17 pub const fn new(buf: &'a [u8], len: usize) -> Self {
18 Self {
19 buf,
20 len,
21 _phantom: PhantomData,
22 }
23 }
24
25 #[inline(always)]
26 pub const fn len(&self) -> usize {
27 self.len
28 }
29
30 #[inline(always)]
31 pub const fn is_empty(&self) -> bool {
32 self.len == 0
33 }
34}
35
36pub struct ZTArrayIter<'a, T> {
38 _phantom: PhantomData<T>,
39 buf: &'a [u8],
40}
41
42impl<'a, T> std::fmt::Debug for ZTArray<'a, T>
43where
44 T: DataType,
45 T::DecodeLifetime<'a>: std::fmt::Debug,
46{
47 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
48 f.debug_list().entries(self).finish()
49 }
50}
51
52impl<'a> ZTArray<'a, u8> {
53 #[inline(always)]
54 pub fn into_slice(self) -> &'a [u8] {
55 self.buf
56 }
57}
58
59impl<'a, T: DataType> IntoIterator for ZTArray<'a, T> {
60 type Item = T::DecodeLifetime<'a>;
61 type IntoIter = ZTArrayIter<'a, T>;
62 fn into_iter(self) -> Self::IntoIter {
63 ZTArrayIter {
64 _phantom: PhantomData,
65 buf: self.buf,
66 }
67 }
68}
69
70impl<'a, T: DataType> IntoIterator for &ZTArray<'a, T> {
71 type Item = T::DecodeLifetime<'a>;
72 type IntoIter = ZTArrayIter<'a, T>;
73 fn into_iter(self) -> Self::IntoIter {
74 ZTArrayIter {
75 _phantom: PhantomData,
76 buf: self.buf,
77 }
78 }
79}
80
81impl<'a, T: DataType> Iterator for ZTArrayIter<'a, T> {
82 type Item = T::DecodeLifetime<'a>;
83 fn next(&mut self) -> Option<Self::Item> {
84 if self.buf[0] == 0 {
85 return None;
86 }
87 let value = T::decode(&mut self.buf).ok()?;
88 Some(value)
89 }
90}
91
92#[derive(Copy, Clone, Default)]
94pub struct Array<'a, L, T> {
95 _phantom: PhantomData<(L, T)>,
96 buf: &'a [u8],
97 len: u32,
98}
99
100impl<'a, L, T> Array<'a, L, T> {
101 pub const fn new(buf: &'a [u8], len: u32) -> Self {
102 Self {
103 buf,
104 len,
105 _phantom: PhantomData,
106 }
107 }
108
109 #[inline(always)]
110 pub const fn len(&self) -> usize {
111 self.len as usize
112 }
113
114 #[inline(always)]
115 pub const fn is_empty(&self) -> bool {
116 self.len == 0
117 }
118}
119
120impl<'a, L> Array<'a, L, u8> {
121 #[inline(always)]
122 pub fn into_slice(self) -> &'a [u8] {
123 self.buf
124 }
125}
126
127impl<'a, L, T> std::fmt::Debug for Array<'a, L, T>
128where
129 for<'b> &'b Self: IntoIterator,
130 for<'b> <&'b Self as IntoIterator>::Item: std::fmt::Debug,
131{
132 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
133 f.debug_list().entries(self).finish()
134 }
135}
136
137pub struct ArrayIter<'a, T> {
139 _phantom: PhantomData<T>,
140 buf: &'a [u8],
141 len: u32,
142}
143
144impl<'a, L, T: DataType> IntoIterator for Array<'a, L, T> {
145 type Item = T::DecodeLifetime<'a>;
146 type IntoIter = ArrayIter<'a, T>;
147 fn into_iter(self) -> Self::IntoIter {
148 ArrayIter {
149 _phantom: PhantomData,
150 buf: self.buf,
151 len: self.len,
152 }
153 }
154}
155
156impl<'a, L, T: DataType> IntoIterator for &Array<'a, L, T> {
157 type Item = T::DecodeLifetime<'a>;
158 type IntoIter = ArrayIter<'a, T>;
159 fn into_iter(self) -> Self::IntoIter {
160 ArrayIter {
161 _phantom: PhantomData,
162 buf: self.buf,
163 len: self.len,
164 }
165 }
166}
167
168impl<'a, T: DataType> Iterator for ArrayIter<'a, T> {
169 type Item = T::DecodeLifetime<'a>;
170 fn next(&mut self) -> Option<Self::Item> {
171 if self.len == 0 {
172 return None;
173 }
174 self.len -= 1;
175 let value = T::decode(&mut self.buf).ok()?;
176 Some(value)
177 }
178}
179
180impl<T> AsRef<[u8]> for Array<'_, T, u8> {
182 fn as_ref(&self) -> &[u8] {
183 &self.buf[..self.len as _]
184 }
185}
186
187impl<'a, L: TryInto<usize>, T: DataTypeFixedSize + DataType> Array<'a, L, T> {
189 pub fn get(&self, index: L) -> Option<T::DecodeLifetime<'a>> {
190 let Ok(index) = index.try_into() else {
191 return None;
192 };
193 let index: usize = index;
194 if index >= self.len as _ {
195 None
196 } else {
197 let mut segment = &self.buf[T::SIZE * index..T::SIZE * (index + 1)];
198 Some(T::decode(&mut segment).unwrap())
200 }
201 }
202}