encdec_base/decode/
tagged.rs

1//! UNSTABLE/INCOMPLETE Decode helper trait for for fields with external length tags
2//!
3
4use core::fmt::Debug;
5
6use crate::Error;
7
8/// Decode helper trait for for fields with external length tags
9/// (length _must_ be specified via `#[encdec(length=...)]` macro)
10pub trait DecodedTagged<'a> {
11    /// Output type (required for lifetime bounds)
12    type Output: Debug;
13
14    /// Error type returned on parse error
15    type Error: Debug;
16
17    /// Decode consumes a slice and explicit length and returns an object
18    fn decode_len(buff: &'a [u8], len: usize) -> Result<Self::Output, Self::Error>;
19}
20
21/// [`DecodedTagged`] impl for byte arrays
22/// (requires `#[encdec(length=...)]` length delimiter)
23impl<'a> DecodedTagged<'a> for &[u8] {
24    type Output = &'a [u8];
25    type Error = Error;
26
27    fn decode_len(buff: &'a [u8], len: usize) -> Result<Self::Output, Self::Error> {
28        if buff.len() < len {
29            return Err(Error::Length);
30        }
31
32        Ok(&buff[..len])
33    }
34}
35
36/// [`DecodedTagged`] impl for string slices (`&str`)
37/// (requires `#[encdec(length=...)]` length delimiter)
38impl<'a> DecodedTagged<'a> for &str {
39    type Output = &'a str;
40    type Error = Error;
41
42    fn decode_len(buff: &'a [u8], len: usize) -> Result<Self::Output, Self::Error> {
43        if buff.len() < len {
44            return Err(Error::Length);
45        }
46
47        match core::str::from_utf8(&buff[..len]) {
48            Ok(v) => Ok(v),
49            Err(_e) => Err(Error::Utf8),
50        }
51    }
52}