1#[derive(Debug)]
6pub enum SResult<Output = (), Error = ()> {
7 Done(usize, Output),
10
11 Needed(usize),
14
15 Error(Error),
17}
18
19impl<Output, Error> SResult<Output, Error> {
20 pub fn is_done(&self) -> bool {
21 match *self {
22 SResult::Done(_, _) => true,
23 _ => false,
24 }
25 }
26
27 pub fn is_needed(&self) -> bool {
28 match *self {
29 SResult::Needed(_) => true,
30 _ => false,
31 }
32 }
33
34 pub fn is_err(&self) -> bool {
35 match *self {
36 SResult::Error(_) => true,
37 _ => false,
38 }
39 }
40
41 pub fn done(self) -> Option<(usize, Output)> {
42 match self {
43 SResult::Done(offset, out) => Some((offset, out)),
44 _ => None,
45 }
46 }
47
48 pub fn needed(self) -> Option<usize> {
49 match self {
50 SResult::Needed(bytes) => Some(bytes),
51 _ => None,
52 }
53 }
54
55 pub fn err(self) -> Option<Error> {
56 match self {
57 SResult::Error(err) => Some(err),
58 _ => None,
59 }
60 }
61}
62
63#[macro_export]
65macro_rules! stream_done {
66 ($bytes:expr, $out:expr) => {
67 return SResult::Done($bytes, $out)
68 };
69 ($bytes:expr) => {
70 stream_done!($bytes, ())
71 };
72}
73
74#[macro_export]
76macro_rules! stream_len_cond {
77 ($buf:expr, $bytes:expr) => {
78 if $buf.len() < $bytes {
79 return SResult::Needed($bytes);
80 }
81 };
82}
83
84#[macro_export]
86macro_rules! stream_err {
87 ($err:expr) => {
88 return SResult::Error($err)
89 };
90 () => {
91 stream_err!(())
92 };
93}
94
95#[macro_export]
97macro_rules! stream_cond {
98 ($cond:expr, $err:expr) => {
99 if !$cond {
100 return SResult::Error($err);
101 }
102 };
103 ($cond:expr) => {
104 stream_cond!($cond, ());
105 };
106}
107
108#[macro_export]
111macro_rules! stream_from_option {
112 ($opt:expr, $err:expr) => {
113 match $opt {
114 Some(opt) => opt,
115 None => stream_err!($err),
116 }
117 };
118 ($opt:expr) => {
119 stream_from_option!($opt, ())
120 };
121}
122
123#[macro_export]
172macro_rules! enc_try {
173 ($result:expr, $offset:expr) => {
174 match $result {
175 SResult::Done(offset, out) => ($offset + offset, out),
176 SResult::Needed(bytes) => { return SResult::Needed($offset + bytes); }
177 SResult::Error(error) => { return SResult::Error(error); }
178 }
179 };
180 ($result:expr)
181 => { enc_try!($result, 0) };
182 ($buf:expr, $offset:expr; $fun:expr)
183 => { enc_try!($fun(&mut $buf[$offset..]), $offset) };
184 ($buf:expr, $offset:expr; $fun:expr, $($args:expr),+)
185 => { enc_try!($fun(&mut $buf[$offset..], $($args),+), $offset) };
186 ($buf:expr, $offset:expr; $object:expr; $fun:ident)
187 => { enc_try!($object.$fun(&mut $buf[$offset..]), $offset) };
188 ($buf:expr, $offset:expr; $object:expr; $fun:ident, $($args:expr),+)
189 => { enc_try!($object.$fun(&mut $buf[$offset..], $($args),+), $offset) };
190 ($buf:expr; $($tts:tt)+)
191 => { enc_try!($buf, 0; $($tts)+) };
192}
193
194#[macro_export]
199macro_rules! enc_consume {
200 ($($tts:tt)*) => { {
201 let (offset, _) = enc_try!($($tts)*);
202 offset
203 } };
204}
205
206#[macro_export]
209macro_rules! dec_try {
210 ($result:expr, $offset:expr) => {
211 match $result {
212 SResult::Done(offset, out) => ($offset + offset, out),
213 SResult::Needed(bytes) => { return SResult::Needed($offset + bytes); }
214 SResult::Error(error) => { return SResult::Error(error); }
215 }
216 };
217 ($result:expr)
218 => { dec_try!($result, 0) };
219 ($buf:expr, $offset:expr; $fun:expr)
220 => { dec_try!($fun(&$buf[$offset..]), $offset) };
221 ($buf:expr, $offset:expr; $fun:expr, $($args:expr),+)
222 => { dec_try!($fun(&$buf[$offset..], $($args),+), $offset) };
223 ($buf:expr, $offset:expr; $object:expr; $fun:ident)
224 => { dec_try!($object.$fun(&$buf[$offset..]), $offset) };
225 ($buf:expr, $offset:expr; $object:expr; $fun:ident, $($args:expr),+)
226 => { dec_try!($object.$fun(&$buf[$offset..], $($args),+), $offset) };
227 ($buf:expr; $($tts:tt)+)
228 => { dec_try!($buf, 0; $($tts)+) };
229}
230
231#[macro_export]
233macro_rules! dec_consume {
234 ($($tts:tt)*) => { {
235 let (offset, _) = dec_try!($($tts)*);
236 offset
237 } };
238}
239
240pub fn encode_u8(buf: &mut [u8], b: u8) -> SResult {
241 stream_len_cond!(buf, 1);
242 buf[0] = b;
243 stream_done!(1);
244}
245
246pub fn encode_u16(buf: &mut [u8], b: u16) -> SResult {
247 stream_len_cond!(buf, 2);
248 buf[0] = (b >> 8) as u8;
249 buf[1] = b as u8;
250 stream_done!(2);
251}
252
253pub fn encode_u32(buf: &mut [u8], b: u32) -> SResult {
254 stream_len_cond!(buf, 4);
255 buf[0] = (b >> 24) as u8;
256 buf[1] = (b >> 16) as u8;
257 buf[2] = (b >> 8) as u8;
258 buf[3] = b as u8;
259 stream_done!(4);
260}
261
262pub fn encode_bytes(buf: &mut [u8], bs: &[u8]) -> SResult {
263 stream_len_cond!(buf, bs.len());
264 buf[..bs.len()].copy_from_slice(bs);
265 stream_done!(bs.len());
266}
267
268pub fn encode_bytes_be(buf: &mut [u8], bs: &[u8]) -> SResult {
270 stream_len_cond!(buf, bs.len());
271 for (i, b) in bs.iter().rev().enumerate() {
272 buf[i] = *b;
273 }
274 stream_done!(bs.len());
275}
276
277pub fn decode_u8(buf: &[u8]) -> SResult<u8> {
278 stream_len_cond!(buf, 1);
279 stream_done!(1, buf[0]);
280}
281
282pub fn decode_u16(buf: &[u8]) -> SResult<u16> {
283 stream_len_cond!(buf, 2);
284 stream_done!(2, (buf[0] as u16) << 8 | (buf[1] as u16));
285}
286
287pub fn decode_u32(buf: &[u8]) -> SResult<u32> {
288 stream_len_cond!(buf, 4);
289 let b = (buf[0] as u32) << 24 | (buf[1] as u32) << 16 | (buf[2] as u32) << 8 | (buf[3] as u32);
290 stream_done!(4, b);
291}
292
293pub fn decode_bytes(buf: &[u8], out: &mut [u8]) -> SResult {
294 stream_len_cond!(buf, out.len());
295 let len = out.len();
296 out.copy_from_slice(&buf[..len]);
297 stream_done!(out.len());
298}
299
300pub fn decode_bytes_be(buf: &[u8], out: &mut [u8]) -> SResult {
302 stream_len_cond!(buf, out.len());
303 for (i, b) in buf[..out.len()].iter().rev().enumerate() {
304 out[i] = *b;
305 }
306 stream_done!(out.len());
307}