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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
use super::prim::CborDataOf;
use super::reader::{Reader, ReaderError};
use super::types::DataOwned;
use std::fmt;

/// Possible errors when decoding an element
#[derive(Debug, Clone)]
pub enum DecodeError {
    /// Underlying reader has an error
    ReaderError(ReaderError),
    /// Reader has some trailing data, when trying to decode an element
    ReaderNotTerminated { remaining_bytes: usize },
    /// Underlying conversion is out of range, it gives the u64 values that was attempted to
    /// be converted, and the range that was expected by the conversion
    OutOfRange { min: u64, max: u64, got: u64 },
    /// Unexpected length whilst decoding type
    UnexpectedLength { expected: usize, got: usize },
    /// A custom error for the decoder
    Custom(String),
}

impl std::error::Error for DecodeError {}

impl fmt::Display for DecodeError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
        write!(f, "{:?}", self)
    }
}

impl From<ReaderError> for DecodeError {
    fn from(r: ReaderError) -> DecodeError {
        DecodeError::ReaderError(r)
    }
}

/// Generic Decode trait to read an element T from the CBOR reader
pub trait Decode: Sized {
    fn decode<'a>(reader: &mut Reader<'a>) -> Result<Self, DecodeError>;
}

macro_rules! assert_range {
    ($got:ident <= $max:literal) => {
        if $got > $max {
            return Err(DecodeError::OutOfRange {
                got: $got,
                min: 0,
                max: $max,
            });
        }
    };
    ($min:literal <= $got:ident <= $max:literal) => {
        if !($got >= $min && $got <= $max) {
            return Err(DecodeError::OutOfRange {
                got: $got,
                min: $min,
                max: $max,
            });
        }
    };
}

impl Decode for DataOwned {
    fn decode<'a>(reader: &mut Reader<'a>) -> Result<Self, DecodeError> {
        let data = reader.data()?;
        Ok(data.owned())
    }
}

impl Decode for bool {
    fn decode<'a>(reader: &mut Reader<'a>) -> Result<Self, DecodeError> {
        reader.bool().map_err(|e| e.into())
    }
}

impl Decode for u8 {
    fn decode<'a>(reader: &mut Reader<'a>) -> Result<Self, DecodeError> {
        let pos = reader.positive()?;
        let val = pos.to_u64();
        assert_range!(val <= 255);
        Ok(val as u8)
    }
}

impl Decode for u16 {
    fn decode<'a>(reader: &mut Reader<'a>) -> Result<Self, DecodeError> {
        let pos = reader.positive()?;
        let val = pos.to_u64();
        assert_range!(val <= 65535);
        Ok(val as u16)
    }
}

impl Decode for u32 {
    fn decode<'a>(reader: &mut Reader<'a>) -> Result<Self, DecodeError> {
        let pos = reader.positive()?;
        let val = pos.to_u64();
        assert_range!(val <= 0xffff_ffff);
        Ok(val as u32)
    }
}

impl Decode for u64 {
    fn decode<'a>(reader: &mut Reader<'a>) -> Result<Self, DecodeError> {
        let pos = reader.positive()?;
        Ok(pos.to_u64())
    }
}

impl Decode for String {
    fn decode<'a>(reader: &mut Reader<'a>) -> Result<Self, DecodeError> {
        let t = reader.text()?;
        Ok(t.to_string())
    }
}

impl<const N: usize> Decode for [u8; N] {
    fn decode<'a>(reader: &mut Reader<'a>) -> Result<Self, DecodeError> {
        let bytes = reader.bytes()?;
        if bytes.len() == N {
            let mut output = [0u8; N];
            // optimise to not do a to_vec() here
            output.copy_from_slice(&bytes.to_vec());
            Ok(output)
        } else {
            Err(DecodeError::UnexpectedLength {
                expected: N,
                got: bytes.len(),
            })
        }
    }
}

impl Decode for Vec<u8> {
    fn decode<'a>(reader: &mut Reader<'a>) -> Result<Self, DecodeError> {
        let t = reader.bytes()?;
        Ok(t.to_vec())
    }
}

impl<T: Decode> Decode for CborDataOf<T> {
    fn decode<'a>(reader: &mut Reader<'a>) -> Result<Self, DecodeError> {
        reader.exact_decodable_data()
    }
}