use base64::Engine as _;
pub(crate) fn encode(bytes: impl AsRef<[u8]>) -> String {
base64::engine::general_purpose::STANDARD.encode(bytes)
}
pub(crate) fn decode(text: impl AsRef<[u8]>) -> Option<Vec<u8>> {
base64::engine::general_purpose::STANDARD.decode(text).ok()
}
#[cfg(feature = "manifest")]
pub(crate) fn encode_url(bytes: impl AsRef<[u8]>) -> String {
base64::engine::general_purpose::URL_SAFE_NO_PAD.encode(bytes)
}
#[cfg(feature = "manifest")]
pub(crate) fn decode_url(text: impl AsRef<[u8]>) -> Option<Vec<u8>> {
base64::engine::general_purpose::URL_SAFE_NO_PAD
.decode(text)
.ok()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn the_standard_dialect_refuses_every_second_spelling() {
assert_eq!(encode([0xFB, 0xFF]), "+/8=");
assert_eq!(decode("+/8=").expect("canonical"), vec![0xFB, 0xFF]);
assert!(decode("+/8").is_none(), "unpadded");
assert!(decode("=+/8").is_none(), "padding in front");
assert!(decode("AC==").is_none(), "non-zero trailing bits");
assert!(
decode("-_8=").is_none(),
"the URL-safe alphabet is a dialect"
);
}
#[cfg(feature = "manifest")]
#[test]
fn the_jose_dialect_is_url_safe_and_carries_no_padding() {
assert_eq!(encode_url([0xFB, 0xFF]), "-_8");
assert_eq!(decode_url("-_8").expect("canonical"), vec![0xFB, 0xFF]);
assert!(decode_url("-_8=").is_none(), "JOSE has no padding");
assert!(
decode_url("+/8").is_none(),
"the standard alphabet is a dialect"
);
}
}