Skip to main content

neco_cbor/
error.rs

1use alloc::string::String;
2use core::fmt;
3
4#[derive(Debug, Clone, PartialEq, Eq)]
5pub struct DecodeError {
6    kind: DecodeErrorKind,
7    position: usize,
8}
9
10impl DecodeError {
11    pub fn new(kind: DecodeErrorKind, position: usize) -> Self {
12        Self { kind, position }
13    }
14
15    pub fn kind(&self) -> &DecodeErrorKind {
16        &self.kind
17    }
18
19    pub fn position(&self) -> usize {
20        self.position
21    }
22}
23
24#[derive(Debug, Clone, PartialEq, Eq)]
25pub enum DecodeErrorKind {
26    UnexpectedEnd,
27    InvalidMajorType(u8),
28    NestingTooDeep,
29    IndefiniteLength,
30    FloatNotAllowed,
31    UnsortedMapKeys,
32    NonCanonicalInteger,
33    DuplicateMapKey,
34    TrailingContent,
35    InvalidUtf8,
36    NonTextMapKey,
37    UnsupportedTag(u64),
38    IntegerOverflow,
39}
40
41#[derive(Debug, Clone, PartialEq, Eq)]
42pub enum AccessError {
43    NotAMap,
44    MissingField(String),
45    TypeMismatch {
46        field: String,
47        expected: &'static str,
48    },
49}
50
51#[derive(Debug, Clone, PartialEq, Eq)]
52pub enum EncodeError {
53    NonTextKeyInDagMode,
54    DuplicateKeyInDagMode,
55    UnsupportedTag(u64),
56    InvalidTag42Payload,
57    InvalidNegativeValue(i64),
58}
59
60impl fmt::Display for DecodeError {
61    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
62        write!(
63            f,
64            "CBOR decode error at position {}: {}",
65            self.position,
66            self.kind()
67        )
68    }
69}
70
71impl fmt::Display for DecodeErrorKind {
72    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
73        match self {
74            Self::UnexpectedEnd => f.write_str("unexpected end of input"),
75            Self::InvalidMajorType(major) => write!(f, "invalid major type {major}"),
76            Self::NestingTooDeep => f.write_str("nesting too deep"),
77            Self::IndefiniteLength => f.write_str("indefinite-length item is not supported"),
78            Self::FloatNotAllowed => f.write_str("floating-point values are not supported"),
79            Self::UnsortedMapKeys => f.write_str("map keys are not sorted in DAG-CBOR order"),
80            Self::NonCanonicalInteger => f.write_str("integer is not encoded canonically"),
81            Self::DuplicateMapKey => f.write_str("duplicate map key"),
82            Self::TrailingContent => f.write_str("trailing content after CBOR value"),
83            Self::InvalidUtf8 => f.write_str("invalid UTF-8"),
84            Self::NonTextMapKey => f.write_str("map key must be text in DAG-CBOR mode"),
85            Self::UnsupportedTag(tag) => write!(f, "unsupported tag {tag}"),
86            Self::IntegerOverflow => f.write_str("integer does not fit in target representation"),
87        }
88    }
89}
90
91impl fmt::Display for AccessError {
92    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
93        match self {
94            Self::NotAMap => f.write_str("value is not a map"),
95            Self::MissingField(field) => write!(f, "missing field \"{field}\""),
96            Self::TypeMismatch { field, expected } => {
97                write!(f, "field \"{field}\": expected {expected}")
98            }
99        }
100    }
101}
102
103impl fmt::Display for EncodeError {
104    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
105        match self {
106            Self::NonTextKeyInDagMode => f.write_str("map key must be text in DAG-CBOR mode"),
107            Self::DuplicateKeyInDagMode => f.write_str("duplicate map key in DAG-CBOR mode"),
108            Self::UnsupportedTag(tag) => write!(f, "unsupported tag {tag}"),
109            Self::InvalidTag42Payload => {
110                f.write_str("tag 42 payload must be a byte string prefixed with 0x00")
111            }
112            Self::InvalidNegativeValue(value) => {
113                write!(f, "negative integer value must be less than zero: {value}")
114            }
115        }
116    }
117}
118
119impl core::error::Error for DecodeError {}
120impl core::error::Error for AccessError {}
121impl core::error::Error for EncodeError {}