ockam_multiaddr/
iter.rs

1use crate::{default_registry, Checked, Code, Error, Registry};
2use unsigned_varint::decode;
3
4/// Iterator over binary protocol values.
5///
6/// The iterator yields as items a triple of:
7///
8/// 1. The input offset of the current protocol item.
9/// 2. The protocol code.
10/// 3. The protocol value.
11///
12#[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
78/// Iterator over textual protocol values.
79///
80/// The iterator yields as items a pair of:
81///
82/// 1. Protocol prefix.
83/// 2. Protocol value.
84///
85pub 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            // TODO: once packet generated locally bypass ABAC rules, return None
115            ("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}