1use crate::{default_registry, Checked, Code, Error, Registry};
2use unsigned_varint::decode;
3
4#[derive(Debug)]
13pub struct BytesIter<'a> {
14 bytes: &'a [u8],
15 offset: usize,
16 is_err: bool,
17 registry: Registry,
18}
19
20impl<'a> BytesIter<'a> {
21 pub fn new(bytes: &'a [u8]) -> Self {
22 BytesIter {
23 bytes,
24 offset: 0,
25 is_err: false,
26 registry: default_registry().clone(),
27 }
28 }
29
30 pub fn with_registry(bytes: &'a [u8], reg: Registry) -> Self {
31 BytesIter {
32 bytes,
33 offset: 0,
34 is_err: false,
35 registry: reg,
36 }
37 }
38
39 pub fn offset(&self) -> usize {
40 self.offset
41 }
42}
43
44impl<'a> Iterator for BytesIter<'a> {
45 type Item = Result<(usize, Code, Checked<&'a [u8]>), Error>;
46
47 fn next(&mut self) -> Option<Self::Item> {
48 if self.offset >= self.bytes.len() || self.is_err {
49 return None;
50 }
51 match decode::u32(&self.bytes[self.offset..]) {
52 Ok((c, bytes)) => {
53 let code = Code::new(c);
54 if let Some(codec) = self.registry.get_by_code(code) {
55 match codec.split_bytes(code, bytes) {
56 Ok((val, rest)) => {
57 let offset = self.offset;
58 self.offset = self.bytes.len() - rest.len();
59 return Some(Ok((offset, code, val)));
60 }
61 Err(e) => {
62 self.is_err = true;
63 return Some(Err(e));
64 }
65 }
66 }
67 self.is_err = true;
68 Some(Err(Error::unregistered(code)))
69 }
70 Err(e) => {
71 self.is_err = true;
72 Some(Err(e.into()))
73 }
74 }
75 }
76}
77
78pub struct StrIter<'a> {
86 string: &'a str,
87 registry: Registry,
88}
89
90impl<'a> StrIter<'a> {
91 pub fn new(string: &'a str) -> Self {
92 StrIter {
93 string,
94 registry: default_registry().clone(),
95 }
96 }
97
98 pub fn with_registry(string: &'a str, reg: Registry) -> Self {
99 StrIter {
100 string,
101 registry: reg,
102 }
103 }
104}
105
106impl<'a> Iterator for StrIter<'a> {
107 type Item = Result<(&'a str, Checked<&'a str>), Error>;
108
109 fn next(&mut self) -> Option<Self::Item> {
110 if self.string.is_empty() {
111 return None;
112 }
113 let (prefix, value) = if self.string == "self" {
114 ("secure", "api")
116 } else {
117 match self.string.split_once('/') {
118 Some(("", s)) => match s.split_once('/') {
119 Some((p, r)) => (p, r),
120 None => (s, ""),
121 },
122 Some((p, s)) => (p, s),
123 None => (self.string, ""),
124 }
125 };
126 if let Some(codec) = self.registry.get_by_prefix(prefix) {
127 match codec.split_str(prefix, value) {
128 Ok((val, rest)) => {
129 self.string = rest;
130 Some(Ok((prefix, val)))
131 }
132 Err(e) => Some(Err(e)),
133 }
134 } else {
135 Some(Err(Error::unregistered_prefix(prefix)))
136 }
137 }
138}