1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
use std_alloc::vec::Vec;
pub use crate::no_alloc::opt::{EnumerateOptNumbers, EnumerateOptNumbersIter, GetOptDelta, OptDelta, OptNumber};
use crate::{no_alloc::{opt_header, opt_len_or_delta},
from_bytes::*};
#[doc = include_str!("../../docs/no_alloc/opt/Opt.md")]
#[derive(Clone, PartialEq, PartialOrd, Debug)]
pub struct Opt {
pub delta: OptDelta,
pub value: OptValue,
}
impl GetOptDelta for Opt {
fn get_delta(&self) -> OptDelta {
self.delta
}
}
#[derive(Clone, PartialEq, PartialOrd, Debug)]
pub struct OptValue(pub Vec<u8>);
impl<I: Iterator<Item = u8>> TryConsumeBytes<I> for Vec<Opt> {
type Error = OptParseError;
fn try_consume_bytes(bytes: &mut I) -> Result<Self, Self::Error> {
let mut opts = Vec::with_capacity(32);
loop {
match Opt::try_consume_bytes(bytes) {
| Ok(opt) => {
opts.push(opt);
},
| Err(OptParseError::OptionsExhausted) => break Ok(opts),
| Err(e) => break Err(e),
}
}
}
}
impl<I: Iterator<Item = u8>> TryConsumeBytes<I> for Opt {
type Error = OptParseError;
fn try_consume_bytes(bytes: &mut I) -> Result<Self, Self::Error> {
let opt_header = opt_header(bytes.by_ref())?;
let delta = OptDelta::try_consume_bytes(&mut core::iter::once(opt_header).chain(bytes.by_ref()))?;
let len = opt_header & 0b00001111;
let len = opt_len_or_delta(len, bytes.by_ref(), OptParseError::ValueLengthReservedValue(15))?;
let value = OptValue::try_consume_n_bytes(len as usize, bytes)?;
Ok(Opt { delta, value })
}
}
impl<I: Iterator<Item = u8>> TryConsumeNBytes<I> for OptValue {
type Error = OptParseError;
fn try_consume_n_bytes(n: usize, bytes: &mut I) -> Result<Self, Self::Error> {
let mut data = Vec::<u8>::with_capacity(n as usize);
data.extend(&mut bytes.take(n));
if data.len() < n {
Err(Self::Error::UnexpectedEndOfStream)
} else {
Ok(OptValue(data))
}
}
}
#[cfg(test)]
mod tests {
use core::iter::{once, repeat};
use super::*;
#[test]
fn parse_opt_value() {
let mut val_1byte = once(2);
let val_1byte = OptValue::try_consume_n_bytes(1, &mut val_1byte).unwrap();
assert_eq!(val_1byte, OptValue(vec![2]));
let data13bytes = repeat(1u8).take(13).collect::<Vec<_>>();
let mut val_13bytes = data13bytes.iter().copied();
let val_13bytes = OptValue::try_consume_n_bytes(13, &mut val_13bytes).unwrap();
assert_eq!(val_13bytes, OptValue(data13bytes));
let data270bytes = repeat(1u8).take(270).collect::<Vec<_>>();
let mut val_270bytes = data270bytes.iter().copied();
let val_270bytes = OptValue::try_consume_n_bytes(270, &mut val_270bytes).unwrap();
assert_eq!(val_270bytes, OptValue(data270bytes));
let errs = [(1, [].into_iter())];
errs.into_iter().for_each(|(n, mut bytes)| {
let del = OptValue::try_consume_n_bytes(n, &mut bytes);
assert_eq!(del, Err(OptParseError::UnexpectedEndOfStream))
});
}
#[test]
fn parse_opt() {
let opt_bytes: [u8; 2] = [0b00000001, 0b00000001];
let opt = Opt::try_consume_bytes(&mut opt_bytes.into_iter()).unwrap();
assert_eq!(opt,
Opt { delta: OptDelta(0),
value: OptValue(vec![1]) });
let opt_bytes: [u8; 5] = [0b00000001, 0b00000001, 0b00010001, 0b00000011, 0b11111111];
let opt = Vec::<Opt>::try_consume_bytes(&mut opt_bytes.into_iter()).unwrap();
assert_eq!(opt,
vec![Opt { delta: OptDelta(0),
value: OptValue(vec![1]) },
Opt { delta: OptDelta(1),
value: OptValue(vec![3]) },]);
}
}