use base64::Engine as _;
use base64::engine::general_purpose::STANDARD as BASE64_STANDARD;
pub fn base64_encode(input: impl AsRef<[u8]>) -> String {
BASE64_STANDARD.encode(input)
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, thiserror::Error)]
#[error("invalid base64 input")]
pub struct Base64DecodeError;
pub fn base64_decode(input: impl AsRef<[u8]>) -> Result<Vec<u8>, Base64DecodeError> {
BASE64_STANDARD.decode(input).map_err(|_| Base64DecodeError)
}
pub fn hex_lower(input: impl AsRef<[u8]>) -> String {
hex::encode(input)
}
pub fn hex_upper(input: impl AsRef<[u8]>) -> String {
hex::encode_upper(input)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn base64_round_trips() {
let original = b"apiKey:abc&randomKey:123&signature:deadbeef";
let encoded = base64_encode(original);
let decoded = base64_decode(&encoded).unwrap();
assert_eq!(decoded, original);
}
#[test]
fn base64_decode_rejects_garbage() {
assert!(base64_decode("not valid base64!!").is_err());
}
#[test]
fn hex_case_variants() {
let bytes = [0xdeu8, 0xad, 0xbe, 0xef];
assert_eq!(hex_lower(bytes), "deadbeef");
assert_eq!(hex_upper(bytes), "DEADBEEF");
}
}