Skip to main content

base64_ng/
errors.rs

1//! Error types for encoding and decoding operations.
2
3/// Encoding error.
4#[derive(Clone, Copy, Debug, Eq, PartialEq)]
5pub enum EncodeError {
6    /// The encoded output length would overflow `usize`.
7    LengthOverflow,
8    /// The requested line wrapping policy is invalid.
9    InvalidLineWrap {
10        /// Requested line length.
11        line_len: usize,
12    },
13    /// The caller-provided input length exceeds the provided buffer.
14    InputTooLarge {
15        /// Requested input bytes.
16        input_len: usize,
17        /// Available buffer bytes.
18        buffer_len: usize,
19    },
20    /// The output buffer is too small.
21    OutputTooSmall {
22        /// Required output bytes.
23        required: usize,
24        /// Available output bytes.
25        available: usize,
26    },
27}
28
29impl core::fmt::Display for EncodeError {
30    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
31        match self {
32            Self::LengthOverflow => f.write_str("base64 output length overflows usize"),
33            Self::InvalidLineWrap { line_len } => {
34                write!(f, "base64 line wrap length {line_len} is invalid")
35            }
36            Self::InputTooLarge {
37                input_len,
38                buffer_len,
39            } => write!(
40                f,
41                "base64 input length {input_len} exceeds buffer length {buffer_len}"
42            ),
43            Self::OutputTooSmall {
44                required,
45                available,
46            } => write!(
47                f,
48                "base64 output buffer too small: required {required}, available {available}"
49            ),
50        }
51    }
52}
53
54#[cfg(feature = "std")]
55impl std::error::Error for EncodeError {}
56
57/// Decoding error.
58#[derive(Clone, Copy, Debug, Eq, PartialEq)]
59pub enum DecodeError {
60    /// The encoded input is malformed, but the decoder intentionally does not
61    /// disclose a more specific error class.
62    InvalidInput,
63    /// The encoded input length is impossible for the selected padding policy.
64    InvalidLength,
65    /// A byte is not valid for the selected alphabet.
66    InvalidByte {
67        /// Byte index in the input.
68        index: usize,
69        /// Invalid byte value.
70        byte: u8,
71    },
72    /// Padding is missing, misplaced, or non-canonical.
73    InvalidPadding {
74        /// Byte index where padding became invalid.
75        index: usize,
76    },
77    /// Line wrapping is missing, misplaced, or uses the wrong line ending.
78    InvalidLineWrap {
79        /// Byte index where line wrapping became invalid.
80        index: usize,
81    },
82    /// The output buffer is too small.
83    OutputTooSmall {
84        /// Required output bytes.
85        required: usize,
86        /// Available output bytes.
87        available: usize,
88    },
89    /// The caller-provided constant-time staging buffer is too small.
90    StagingTooSmall {
91        /// Required staging bytes.
92        required: usize,
93        /// Available staging bytes.
94        available: usize,
95    },
96}
97
98impl core::fmt::Display for DecodeError {
99    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
100        match self {
101            Self::InvalidInput => f.write_str("malformed base64 input"),
102            Self::InvalidLength => f.write_str("invalid base64 input length"),
103            Self::InvalidByte { index, byte } => {
104                write!(f, "invalid base64 byte 0x{byte:02x} at index {index}")
105            }
106            Self::InvalidPadding { index } => write!(f, "invalid base64 padding at index {index}"),
107            Self::InvalidLineWrap { index } => {
108                write!(f, "invalid base64 line wrapping at index {index}")
109            }
110            Self::OutputTooSmall {
111                required,
112                available,
113            } => write!(
114                f,
115                "base64 decode output buffer too small: required {required}, available {available}"
116            ),
117            Self::StagingTooSmall {
118                required,
119                available,
120            } => write!(
121                f,
122                "base64 decode staging buffer too small: required {required}, available {available}"
123            ),
124        }
125    }
126}
127
128impl DecodeError {
129    pub(crate) fn with_index_offset(self, offset: usize) -> Self {
130        match self {
131            Self::InvalidByte { index, byte } => Self::InvalidByte {
132                index: index + offset,
133                byte,
134            },
135            Self::InvalidPadding { index } => Self::InvalidPadding {
136                index: index + offset,
137            },
138            Self::InvalidLineWrap { index } => Self::InvalidLineWrap {
139                index: index + offset,
140            },
141            Self::InvalidInput
142            | Self::InvalidLength
143            | Self::OutputTooSmall { .. }
144            | Self::StagingTooSmall { .. } => self,
145        }
146    }
147}
148
149#[cfg(feature = "std")]
150impl std::error::Error for DecodeError {}