1#[derive(Clone, Copy, Debug, Eq, PartialEq)]
5pub enum EncodeError {
6 LengthOverflow,
8 InvalidLineWrap {
10 line_len: usize,
12 },
13 InputTooLarge {
15 input_len: usize,
17 buffer_len: usize,
19 },
20 OutputTooSmall {
22 required: usize,
24 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#[derive(Clone, Copy, Debug, Eq, PartialEq)]
59pub enum DecodeError {
60 InvalidInput,
63 InvalidLength,
65 InvalidByte {
67 index: usize,
69 byte: u8,
71 },
72 InvalidPadding {
74 index: usize,
76 },
77 InvalidLineWrap {
79 index: usize,
81 },
82 OutputTooSmall {
84 required: usize,
86 available: usize,
88 },
89 StagingTooSmall {
91 required: usize,
93 available: usize,
95 },
96}
97
98#[derive(Clone, Copy, Debug, Eq, PartialEq)]
103#[non_exhaustive]
104pub enum DecodeErrorKind {
105 InvalidInput,
108 InvalidLength,
110 InvalidByte,
112 InvalidPadding,
114 InvalidLineWrap,
116 OutputTooSmall,
118 StagingTooSmall,
120}
121
122impl DecodeErrorKind {
123 #[must_use]
125 pub const fn as_str(self) -> &'static str {
126 match self {
127 Self::InvalidInput => "invalid-input",
128 Self::InvalidLength => "invalid-length",
129 Self::InvalidByte => "invalid-byte",
130 Self::InvalidPadding => "invalid-padding",
131 Self::InvalidLineWrap => "invalid-line-wrap",
132 Self::OutputTooSmall => "output-too-small",
133 Self::StagingTooSmall => "staging-too-small",
134 }
135 }
136}
137
138impl core::fmt::Display for DecodeErrorKind {
139 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
140 f.write_str(self.as_str())
141 }
142}
143
144impl core::fmt::Display for DecodeError {
145 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
146 match self {
147 Self::InvalidInput => f.write_str("malformed base64 input"),
148 Self::InvalidLength => f.write_str("invalid base64 input length"),
149 Self::InvalidByte { index, byte } => {
150 write!(f, "invalid base64 byte 0x{byte:02x} at index {index}")
151 }
152 Self::InvalidPadding { index } => write!(f, "invalid base64 padding at index {index}"),
153 Self::InvalidLineWrap { index } => {
154 write!(f, "invalid base64 line wrapping at index {index}")
155 }
156 Self::OutputTooSmall {
157 required,
158 available,
159 } => write!(
160 f,
161 "base64 decode output buffer too small: required {required}, available {available}"
162 ),
163 Self::StagingTooSmall {
164 required,
165 available,
166 } => write!(
167 f,
168 "base64 decode staging buffer too small: required {required}, available {available}"
169 ),
170 }
171 }
172}
173
174impl DecodeError {
175 #[must_use]
182 pub const fn kind(self) -> DecodeErrorKind {
183 match self {
184 Self::InvalidInput => DecodeErrorKind::InvalidInput,
185 Self::InvalidLength => DecodeErrorKind::InvalidLength,
186 Self::InvalidByte { .. } => DecodeErrorKind::InvalidByte,
187 Self::InvalidPadding { .. } => DecodeErrorKind::InvalidPadding,
188 Self::InvalidLineWrap { .. } => DecodeErrorKind::InvalidLineWrap,
189 Self::OutputTooSmall { .. } => DecodeErrorKind::OutputTooSmall,
190 Self::StagingTooSmall { .. } => DecodeErrorKind::StagingTooSmall,
191 }
192 }
193
194 pub(crate) fn with_index_offset(self, offset: usize) -> Self {
195 match self {
196 Self::InvalidByte { index, byte } => Self::InvalidByte {
197 index: index + offset,
198 byte,
199 },
200 Self::InvalidPadding { index } => Self::InvalidPadding {
201 index: index + offset,
202 },
203 Self::InvalidLineWrap { index } => Self::InvalidLineWrap {
204 index: index + offset,
205 },
206 Self::InvalidInput
207 | Self::InvalidLength
208 | Self::OutputTooSmall { .. }
209 | Self::StagingTooSmall { .. } => self,
210 }
211 }
212}
213
214#[cfg(feature = "std")]
215impl std::error::Error for DecodeError {}