cbor_data/validated/
iterators.rs1use super::CborIter;
2use crate::Cbor;
3use std::{
4 borrow::Cow,
5 fmt::{Debug, Display, Formatter, Write},
6 io::Read,
7};
8
9#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
16pub struct StringIter<'a>(CborIter<'a>);
17
18impl<'a> StringIter<'a> {
19 pub(crate) fn new(bytes: &'a [u8], len: Option<u64>) -> Self {
20 Self(CborIter::new(bytes, len))
21 }
22
23 pub fn is_indefinite(&self) -> bool {
29 self.0.size().is_none()
30 }
31
32 pub fn is_empty(&self) -> bool {
36 let mut this = *self;
37 this.next().is_none()
38 }
39
40 pub fn as_str(&self) -> Option<&'a str> {
44 let mut this = *self;
45 if let Some(first) = this.next() {
46 if this.next().is_none() {
47 Some(first)
48 } else {
49 None
50 }
51 } else {
52 Some("")
53 }
54 }
55
56 pub fn as_cow(&self) -> Cow<'a, str> {
58 if let Some(s) = self.as_str() {
59 Cow::Borrowed(s)
60 } else {
61 Cow::Owned(self.collect())
62 }
63 }
64
65 pub fn len(&self) -> usize {
67 self.map(|v| v.len()).sum()
68 }
69}
70
71impl<'a> Debug for StringIter<'a> {
72 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
73 f.write_str("StringIter")
74 }
75}
76
77impl<'a> Display for StringIter<'a> {
78 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
79 for s in *self {
80 f.write_str(s)?;
81 }
82 Ok(())
83 }
84}
85
86impl<'a> Iterator for StringIter<'a> {
87 type Item = &'a str;
88
89 fn next(&mut self) -> Option<Self::Item> {
90 let v = self
91 .0
92 .next()?
93 .0
94 .expect("string fragments must be in definite size encoding");
95 Some(unsafe { std::str::from_utf8_unchecked(v) })
96 }
97}
98
99impl<'a, S: AsRef<str>> PartialEq<S> for StringIter<'a> {
100 fn eq(&self, other: &S) -> bool {
101 let this = *self;
102 let mut other = other.as_ref();
103 for prefix in this {
104 if other.starts_with(prefix) {
105 other = &other[prefix.len()..];
106 } else {
107 return false;
108 }
109 }
110 other.is_empty()
111 }
112}
113
114#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
121pub struct BytesIter<'a>(CborIter<'a>, &'a [u8]);
122
123impl<'a> BytesIter<'a> {
124 pub(crate) fn new(bytes: &'a [u8], len: Option<u64>) -> Self {
125 Self(CborIter::new(bytes, len), b"")
126 }
127
128 pub fn is_indefinite(&self) -> bool {
134 self.0.size().is_none()
135 }
136
137 pub fn is_empty(&self) -> bool {
141 let mut this = *self;
142 this.next().is_none()
143 }
144
145 pub fn as_slice(&self) -> Option<&'a [u8]> {
149 let mut this = *self;
150 if let Some(first) = this.next() {
151 if this.next().is_none() {
152 Some(first)
153 } else {
154 None
155 }
156 } else {
157 Some(b"")
158 }
159 }
160
161 pub fn as_cow(&self) -> Cow<'a, [u8]> {
163 if let Some(s) = self.as_slice() {
164 Cow::Borrowed(s)
165 } else {
166 let mut v = Vec::new();
167 for b in *self {
168 v.extend_from_slice(b);
169 }
170 Cow::Owned(v)
171 }
172 }
173
174 pub fn to_vec(self) -> Vec<u8> {
176 let mut ret = Vec::new();
177 for v in self {
178 ret.extend_from_slice(v);
179 }
180 ret
181 }
182
183 pub fn len(&self) -> usize {
185 self.map(|v| v.len()).sum()
186 }
187}
188
189impl<'a> Debug for BytesIter<'a> {
190 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
191 f.write_str("BytesIter")
192 }
193}
194
195impl<'a> Display for BytesIter<'a> {
196 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
197 let mut first = true;
198 for b in *self {
199 if first {
200 first = false;
201 } else {
202 f.write_char(' ')?;
203 }
204 for byte in b {
205 write!(f, "{:02x}", byte)?;
206 }
207 }
208 Ok(())
209 }
210}
211
212impl<'a> Iterator for BytesIter<'a> {
213 type Item = &'a [u8];
214
215 fn next(&mut self) -> Option<Self::Item> {
216 Some(
217 self.0
218 .next()?
219 .0
220 .expect("byte string fragments must be in definite size encoding"),
221 )
222 }
223}
224
225impl<'a> Read for BytesIter<'a> {
226 fn read(&mut self, mut buf: &mut [u8]) -> std::io::Result<usize> {
227 let mut in_hand = self.1;
228 let mut read = 0;
229 loop {
230 let transfer = in_hand.len().min(buf.len());
231 let (left, right) = buf.split_at_mut(transfer);
232 left.copy_from_slice(&in_hand[..transfer]);
233 in_hand = &in_hand[transfer..];
234 buf = right;
235 read += transfer;
236 if buf.is_empty() {
237 break;
238 }
239 if let Some(bytes) = self.next() {
241 in_hand = bytes;
242 } else {
243 break;
244 }
245 }
246 self.1 = in_hand;
247 Ok(read)
248 }
249}
250
251impl<'a, S: AsRef<[u8]>> PartialEq<S> for BytesIter<'a> {
252 fn eq(&self, other: &S) -> bool {
253 let this = *self;
254 let mut other = other.as_ref();
255 for prefix in this {
256 if other.starts_with(prefix) {
257 other = &other[prefix.len()..];
258 } else {
259 return false;
260 }
261 }
262 other.is_empty()
263 }
264}
265
266#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
268pub struct ArrayIter<'a>(CborIter<'a>);
269
270impl<'a> ArrayIter<'a> {
271 pub(crate) fn new(bytes: &'a [u8], len: Option<u64>) -> Self {
272 Self(CborIter::new(bytes, len))
273 }
274
275 pub fn size(&self) -> Option<u64> {
278 self.0.size()
279 }
280}
281
282impl<'a> Debug for ArrayIter<'a> {
283 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
284 f.write_str("ArrayIter")
285 }
286}
287impl<'a> Iterator for ArrayIter<'a> {
288 type Item = &'a Cbor;
289
290 fn next(&mut self) -> Option<Self::Item> {
291 Some(self.0.next()?.1)
292 }
293}
294
295#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
297pub struct DictIter<'a>(CborIter<'a>);
298
299impl<'a> DictIter<'a> {
300 pub(crate) fn new(bytes: &'a [u8], len: Option<u64>) -> Self {
301 Self(CborIter::new(bytes, len.map(|x| x * 2)))
302 }
303
304 pub fn size(&self) -> Option<u64> {
307 self.0.size().map(|x| x / 2)
308 }
309}
310
311impl<'a> Debug for DictIter<'a> {
312 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
313 f.write_str("DictIter")
314 }
315}
316impl<'a> Iterator for DictIter<'a> {
317 type Item = (&'a Cbor, &'a Cbor);
318
319 fn next(&mut self) -> Option<Self::Item> {
320 Some((self.0.next()?.1, self.0.next()?.1))
321 }
322}