Skip to main content

codec_cbor/deterministic/
error.rs

1// SPDX-FileCopyrightText: Copyright © 2026 ReallyMe LLC. All rights reserved
2//
3// SPDX-License-Identifier: Apache-2.0
4
5use thiserror::Error;
6
7/// Errors raised by deterministic-CBOR profile construction and validation.
8#[derive(Debug, Clone, Copy, Error, PartialEq, Eq)]
9#[non_exhaustive]
10pub enum DeterministicCborProfileError {
11    /// Negative integer variants must remain strictly negative so each integer
12    /// has exactly one semantic representation.
13    #[error("deterministic CBOR: negative integer must be less than zero")]
14    NegativeIntegerMustBeNegative,
15}
16
17/// Error returned by deterministic generic-CBOR encoding and decoding.
18///
19/// Variants intentionally carry no caller text, byte strings, or raw input.
20/// This keeps FFI and SDK error mapping deterministic and prevents accidental
21/// PII disclosure in logs or telemetry.
22#[derive(Debug, Clone, Copy, Error, PartialEq, Eq)]
23#[non_exhaustive]
24pub enum DeterministicCborError {
25    /// Extra bytes remain after decoding the top-level value.
26    #[error("deterministic CBOR: trailing bytes after top-level value")]
27    TrailingBytes,
28
29    /// Input ended before the current value was fully decoded.
30    #[error("deterministic CBOR: unexpected end of input")]
31    UnexpectedEnd,
32
33    /// The encoded input exceeded the deterministic-CBOR boundary cap.
34    #[error("deterministic CBOR: input too large")]
35    InputTooLarge,
36
37    /// Encoding would exceed the deterministic-CBOR output cap.
38    #[error("deterministic CBOR: encoded output too large")]
39    OutputTooLarge,
40
41    /// Computing a buffer offset, length, or capacity would overflow.
42    #[error("deterministic CBOR: offset arithmetic overflow")]
43    OffsetOverflow,
44
45    /// A declared length does not fit in the current platform's `usize`.
46    #[error("deterministic CBOR: length does not fit in platform usize")]
47    LengthTooLarge,
48
49    /// A negative integer is outside the supported `i64::MIN..=-1` range.
50    #[error("deterministic CBOR: negative integer outside supported range")]
51    NegativeIntegerOutOfRange,
52
53    /// A negative-integer semantic value was zero or positive.
54    #[error("deterministic CBOR: negative integer must be less than zero")]
55    NegativeIntegerMustBeNegative,
56
57    /// An integer or length used a longer-than-minimal encoding.
58    #[error("deterministic CBOR: non-canonical integer or length encoding")]
59    NonCanonicalInteger,
60
61    /// The numeric argument bytes were truncated.
62    #[error("deterministic CBOR: truncated numeric argument")]
63    TruncatedArgument,
64
65    /// A byte or text string ended before its declared length was read.
66    #[error("deterministic CBOR: truncated byte or text string")]
67    TruncatedBytes,
68
69    /// A text string contained bytes that are not valid UTF-8.
70    #[error("deterministic CBOR: invalid UTF-8 string")]
71    InvalidUtf8,
72
73    /// A map key used a type outside the supported deterministic-CBOR key set.
74    #[error("deterministic CBOR: unsupported map key type")]
75    UnsupportedMapKeyType,
76
77    /// A map contained the same semantic key more than once.
78    #[error("deterministic CBOR: duplicate map key")]
79    DuplicateMapKey,
80
81    /// Map keys were not in RFC 8949 deterministic order.
82    #[error("deterministic CBOR: map keys out of deterministic order")]
83    MapKeysOutOfOrder,
84
85    /// A CBOR simple value outside false, true, or null was found.
86    #[error("deterministic CBOR: unsupported simple value")]
87    UnsupportedSimpleValue,
88
89    /// A CBOR major type outside the supported profile was found.
90    #[error("deterministic CBOR: unsupported major type")]
91    UnsupportedMajorType,
92
93    /// Indefinite length or another unsupported additional-info value appeared.
94    #[error("deterministic CBOR: unsupported additional information")]
95    UnsupportedAdditionalInfo,
96
97    /// Nesting exceeded the deterministic-CBOR profile limit.
98    #[error("deterministic CBOR: nesting depth limit exceeded")]
99    DepthExceeded,
100
101    /// The semantic node count exceeded the deterministic-CBOR profile limit.
102    #[error("deterministic CBOR: node limit exceeded")]
103    NodeLimitExceeded,
104
105    /// A single array or map exceeded the per-container entry limit.
106    #[error("deterministic CBOR: container entry limit exceeded")]
107    ContainerEntriesExceeded,
108
109    /// Aggregate UTF-8 text bytes exceeded the deterministic-CBOR profile cap.
110    #[error("deterministic CBOR: aggregate text byte limit exceeded")]
111    AggregateTextBytesExceeded,
112
113    /// Aggregate byte-string bytes exceeded the deterministic-CBOR profile cap.
114    #[error("deterministic CBOR: aggregate byte-string limit exceeded")]
115    AggregateByteStringBytesExceeded,
116
117    /// A declared container length is larger than the remaining input can hold.
118    #[error("deterministic CBOR: declared container length exceeds remaining input")]
119    ContainerLengthExceedsInput,
120
121    /// Encoder preflight and emission disagreed, which indicates an internal bug.
122    #[error("deterministic CBOR: preflight length mismatch")]
123    PreflightLengthMismatch,
124
125    /// A bounded internal owner could not reserve its required allocation.
126    #[error("deterministic CBOR: bounded allocation failed")]
127    AllocationFailure,
128}
129
130impl From<DeterministicCborProfileError> for DeterministicCborError {
131    fn from(error: DeterministicCborProfileError) -> Self {
132        match error {
133            DeterministicCborProfileError::NegativeIntegerMustBeNegative => {
134                Self::NegativeIntegerMustBeNegative
135            }
136        }
137    }
138}