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
15pub trait EngineBytesExt<A, const PAD: bool>
17where
18 A: Alphabet,
19{
20 fn encode_bytes(&self, input: impl AsRef<[u8]>) -> Result<Bytes, EncodeError>;
26
27 fn decode_bytes(&self, input: impl AsRef<[u8]>) -> Result<Bytes, DecodeError>;
33
34 fn encode_buf<B>(&self, input: B) -> Result<Bytes, EncodeError>
43 where
44 B: Buf;
45
46 fn decode_buf<B>(&self, input: B) -> Result<Bytes, DecodeError>
52 where
53 B: Buf;
54
55 fn encode_buf_to_mut<B, M>(&self, input: B, output: &mut M) -> Result<usize, EncodeError>
62 where
63 B: Buf,
64 M: BufMut;
65
66 fn decode_buf_to_mut<B, M>(&self, input: B, output: &mut M) -> Result<usize, DecodeError>
74 where
75 B: Buf,
76 M: BufMut;
77}
78
79impl<A, const PAD: bool> EngineBytesExt<A, PAD> for Engine<A, PAD>
80where
81 A: Alphabet,
82{
83 fn encode_bytes(&self, input: impl AsRef<[u8]>) -> Result<Bytes, EncodeError> {
84 self.encode_vec(input.as_ref()).map(Bytes::from)
85 }
86
87 fn decode_bytes(&self, input: impl AsRef<[u8]>) -> Result<Bytes, DecodeError> {
88 self.decode_vec(input.as_ref()).map(Bytes::from)
89 }
90
91 fn encode_buf<B>(&self, input: B) -> Result<Bytes, EncodeError>
92 where
93 B: Buf,
94 {
95 self.encode_bytes(collect_buf(input))
96 }
97
98 fn decode_buf<B>(&self, input: B) -> Result<Bytes, DecodeError>
99 where
100 B: Buf,
101 {
102 self.decode_bytes(collect_buf(input))
103 }
104
105 fn encode_buf_to_mut<B, M>(&self, input: B, output: &mut M) -> Result<usize, EncodeError>
106 where
107 B: Buf,
108 M: BufMut,
109 {
110 let encoded = self.encode_buf(input)?;
111 let len = encoded.len();
112 if output.remaining_mut() < len {
113 return Err(EncodeError::OutputTooSmall {
114 required: len,
115 available: output.remaining_mut(),
116 });
117 }
118 output.put_slice(&encoded);
119 Ok(len)
120 }
121
122 fn decode_buf_to_mut<B, M>(&self, input: B, output: &mut M) -> Result<usize, DecodeError>
123 where
124 B: Buf,
125 M: BufMut,
126 {
127 let decoded = self.decode_buf(input)?;
128 let len = decoded.len();
129 if output.remaining_mut() < len {
130 return Err(DecodeError::OutputTooSmall {
131 required: len,
132 available: output.remaining_mut(),
133 });
134 }
135 output.put_slice(&decoded);
136 Ok(len)
137 }
138}
139
140fn collect_buf<B>(mut input: B) -> Vec<u8>
141where
142 B: Buf,
143{
144 let mut output = Vec::with_capacity(input.remaining());
145 while input.has_remaining() {
146 let chunk = input.chunk();
147 output.extend_from_slice(chunk);
148 let len = chunk.len();
149 input.advance(len);
150 }
151 output
152}