1#![cfg_attr(not(feature = "std"), no_std)]
2#![deny(unsafe_code)]
3#![deny(missing_docs)]
4#![deny(clippy::all)]
5#![deny(clippy::pedantic)]
6
7extern crate alloc;
10
11use alloc::vec::Vec;
12use base64_ng::{Alphabet, DecodeError, EncodeError, Engine};
13use bytes::{Buf, BufMut, Bytes};
14
15#[derive(Clone, Copy, Debug, Eq, PartialEq)]
17pub enum BytesEncodeError {
18 InputTooLarge {
20 input_len: usize,
22 max_input_len: usize,
24 },
25 Encode(EncodeError),
27}
28
29impl core::fmt::Display for BytesEncodeError {
30 fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
31 match self {
32 Self::InputTooLarge {
33 input_len,
34 max_input_len,
35 } => write!(
36 formatter,
37 "bytes input length {input_len} exceeds limit {max_input_len}"
38 ),
39 Self::Encode(error) => core::fmt::Display::fmt(error, formatter),
40 }
41 }
42}
43
44#[cfg(feature = "std")]
45impl std::error::Error for BytesEncodeError {
46 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
47 match self {
48 Self::InputTooLarge { .. } => None,
49 Self::Encode(error) => Some(error),
50 }
51 }
52}
53
54impl From<EncodeError> for BytesEncodeError {
55 fn from(error: EncodeError) -> Self {
56 Self::Encode(error)
57 }
58}
59
60#[derive(Clone, Copy, Debug, Eq, PartialEq)]
62pub enum BytesDecodeError {
63 InputTooLarge {
65 input_len: usize,
67 max_input_len: usize,
69 },
70 Decode(DecodeError),
72}
73
74impl core::fmt::Display for BytesDecodeError {
75 fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
76 match self {
77 Self::InputTooLarge {
78 input_len,
79 max_input_len,
80 } => write!(
81 formatter,
82 "bytes input length {input_len} exceeds limit {max_input_len}"
83 ),
84 Self::Decode(error) => core::fmt::Display::fmt(error, formatter),
85 }
86 }
87}
88
89#[cfg(feature = "std")]
90impl std::error::Error for BytesDecodeError {
91 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
92 match self {
93 Self::InputTooLarge { .. } => None,
94 Self::Decode(error) => Some(error),
95 }
96 }
97}
98
99impl From<DecodeError> for BytesDecodeError {
100 fn from(error: DecodeError) -> Self {
101 Self::Decode(error)
102 }
103}
104
105pub trait EngineBytesExt<A, const PAD: bool>
107where
108 A: Alphabet,
109{
110 fn encode_bytes(&self, input: impl AsRef<[u8]>) -> Result<Bytes, EncodeError>;
116
117 fn decode_bytes(&self, input: impl AsRef<[u8]>) -> Result<Bytes, DecodeError>;
123
124 fn encode_buf<B>(&self, input: B) -> Result<Bytes, EncodeError>
133 where
134 B: Buf;
135
136 fn encode_buf_limited<B>(
149 &self,
150 input: B,
151 max_input_len: usize,
152 ) -> Result<Bytes, BytesEncodeError>
153 where
154 B: Buf;
155
156 fn decode_buf<B>(&self, input: B) -> Result<Bytes, DecodeError>
162 where
163 B: Buf;
164
165 fn decode_buf_limited<B>(
178 &self,
179 input: B,
180 max_input_len: usize,
181 ) -> Result<Bytes, BytesDecodeError>
182 where
183 B: Buf;
184
185 fn encode_buf_to_mut<B, M>(&self, input: B, output: &mut M) -> Result<usize, EncodeError>
192 where
193 B: Buf,
194 M: BufMut;
195
196 fn encode_buf_to_mut_limited<B, M>(
206 &self,
207 input: B,
208 output: &mut M,
209 max_input_len: usize,
210 ) -> Result<usize, BytesEncodeError>
211 where
212 B: Buf,
213 M: BufMut;
214
215 fn decode_buf_to_mut<B, M>(&self, input: B, output: &mut M) -> Result<usize, DecodeError>
223 where
224 B: Buf,
225 M: BufMut;
226
227 fn decode_buf_to_mut_limited<B, M>(
237 &self,
238 input: B,
239 output: &mut M,
240 max_input_len: usize,
241 ) -> Result<usize, BytesDecodeError>
242 where
243 B: Buf,
244 M: BufMut;
245}
246
247impl<A, const PAD: bool> EngineBytesExt<A, PAD> for Engine<A, PAD>
248where
249 A: Alphabet,
250{
251 fn encode_bytes(&self, input: impl AsRef<[u8]>) -> Result<Bytes, EncodeError> {
252 self.encode_vec(input.as_ref()).map(Bytes::from)
253 }
254
255 fn decode_bytes(&self, input: impl AsRef<[u8]>) -> Result<Bytes, DecodeError> {
256 self.decode_vec(input.as_ref()).map(Bytes::from)
257 }
258
259 fn encode_buf<B>(&self, input: B) -> Result<Bytes, EncodeError>
260 where
261 B: Buf,
262 {
263 self.encode_bytes(collect_buf(input))
264 }
265
266 fn encode_buf_limited<B>(
267 &self,
268 input: B,
269 max_input_len: usize,
270 ) -> Result<Bytes, BytesEncodeError>
271 where
272 B: Buf,
273 {
274 let input =
275 collect_buf_limited(input, max_input_len).map_err(|(input_len, max_input_len)| {
276 BytesEncodeError::InputTooLarge {
277 input_len,
278 max_input_len,
279 }
280 })?;
281 self.encode_bytes(input).map_err(BytesEncodeError::Encode)
282 }
283
284 fn decode_buf<B>(&self, input: B) -> Result<Bytes, DecodeError>
285 where
286 B: Buf,
287 {
288 self.decode_bytes(collect_buf(input))
289 }
290
291 fn decode_buf_limited<B>(
292 &self,
293 input: B,
294 max_input_len: usize,
295 ) -> Result<Bytes, BytesDecodeError>
296 where
297 B: Buf,
298 {
299 let input =
300 collect_buf_limited(input, max_input_len).map_err(|(input_len, max_input_len)| {
301 BytesDecodeError::InputTooLarge {
302 input_len,
303 max_input_len,
304 }
305 })?;
306 self.decode_bytes(input).map_err(BytesDecodeError::Decode)
307 }
308
309 fn encode_buf_to_mut<B, M>(&self, input: B, output: &mut M) -> Result<usize, EncodeError>
310 where
311 B: Buf,
312 M: BufMut,
313 {
314 let encoded = self.encode_buf(input)?;
315 let len = encoded.len();
316 if output.remaining_mut() < len {
317 return Err(EncodeError::OutputTooSmall {
318 required: len,
319 available: output.remaining_mut(),
320 });
321 }
322 output.put_slice(&encoded);
323 Ok(len)
324 }
325
326 fn encode_buf_to_mut_limited<B, M>(
327 &self,
328 input: B,
329 output: &mut M,
330 max_input_len: usize,
331 ) -> Result<usize, BytesEncodeError>
332 where
333 B: Buf,
334 M: BufMut,
335 {
336 let encoded = self.encode_buf_limited(input, max_input_len)?;
337 let len = encoded.len();
338 if output.remaining_mut() < len {
339 return Err(BytesEncodeError::Encode(EncodeError::OutputTooSmall {
340 required: len,
341 available: output.remaining_mut(),
342 }));
343 }
344 output.put_slice(&encoded);
345 Ok(len)
346 }
347
348 fn decode_buf_to_mut<B, M>(&self, input: B, output: &mut M) -> Result<usize, DecodeError>
349 where
350 B: Buf,
351 M: BufMut,
352 {
353 let decoded = self.decode_buf(input)?;
354 let len = decoded.len();
355 if output.remaining_mut() < len {
356 return Err(DecodeError::OutputTooSmall {
357 required: len,
358 available: output.remaining_mut(),
359 });
360 }
361 output.put_slice(&decoded);
362 Ok(len)
363 }
364
365 fn decode_buf_to_mut_limited<B, M>(
366 &self,
367 input: B,
368 output: &mut M,
369 max_input_len: usize,
370 ) -> Result<usize, BytesDecodeError>
371 where
372 B: Buf,
373 M: BufMut,
374 {
375 let decoded = self.decode_buf_limited(input, max_input_len)?;
376 let len = decoded.len();
377 if output.remaining_mut() < len {
378 return Err(BytesDecodeError::Decode(DecodeError::OutputTooSmall {
379 required: len,
380 available: output.remaining_mut(),
381 }));
382 }
383 output.put_slice(&decoded);
384 Ok(len)
385 }
386}
387
388fn collect_buf<B>(mut input: B) -> Vec<u8>
389where
390 B: Buf,
391{
392 let mut output = Vec::with_capacity(input.remaining());
393 while input.has_remaining() {
394 let chunk = input.chunk();
395 output.extend_from_slice(chunk);
396 let len = chunk.len();
397 input.advance(len);
398 }
399 output
400}
401
402fn collect_buf_limited<B>(input: B, max_input_len: usize) -> Result<Vec<u8>, (usize, usize)>
403where
404 B: Buf,
405{
406 let input_len = input.remaining();
407 if input_len > max_input_len {
408 return Err((input_len, max_input_len));
409 }
410
411 Ok(collect_buf(input))
412}