base64_url/
decode.rs

1use alloc::vec::Vec;
2
3use base64::Engine;
4
5/// Decode a Base64-URL string to data.
6#[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/// Decode a Base64-URL string to data and directly store into a mutable `Vec<u8>` reference by concatenating them and return the slice of the decoded data.
12#[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/// Decode a Base64-URL string to data into a slice and return the slice with a valid length.
40#[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}