1use alloc::vec::Vec;
2
3use base64::Engine;
4
5#[inline]
7pub fn decode<T: ?Sized + AsRef<[u8]>>(input: &T) -> Result<Vec<u8>, base64::DecodeError> {
8 base64::engine::general_purpose::URL_SAFE_NO_PAD.decode(input)
9}
10
11#[inline]
13pub fn decode_to_vec<'a, T: ?Sized + AsRef<[u8]>>(
14 input: &T,
15 output: &'a mut Vec<u8>,
16) -> Result<&'a [u8], base64::DecodeSliceError> {
17 let bytes = input.as_ref();
18
19 let current_length = output.len();
20
21 let original_max_length = ((bytes.len() + 3) >> 2) * 3;
22
23 output.reserve(original_max_length);
24
25 #[allow(clippy::uninit_vec)]
26 unsafe {
27 output.set_len(current_length + original_max_length);
28 }
29
30 let original_length = decode_to_slice(bytes, &mut output[current_length..])?.len();
31
32 unsafe {
33 output.set_len(current_length + original_length);
34 }
35
36 Ok(&output[current_length..])
37}
38
39#[inline]
41pub fn decode_to_slice<'a, T: ?Sized + AsRef<[u8]>>(
42 input: &T,
43 output: &'a mut [u8],
44) -> Result<&'a [u8], base64::DecodeSliceError> {
45 let length = base64::engine::general_purpose::URL_SAFE_NO_PAD.decode_slice(input, output)?;
46
47 Ok(&output[..length])
48}