extrapaytr_crypto/
encoding.rs1use base64::Engine as _;
2use base64::engine::general_purpose::STANDARD as BASE64_STANDARD;
3
4pub fn base64_encode(input: impl AsRef<[u8]>) -> String {
5 BASE64_STANDARD.encode(input)
6}
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, thiserror::Error)]
9#[error("invalid base64 input")]
10pub struct Base64DecodeError;
11
12pub fn base64_decode(input: impl AsRef<[u8]>) -> Result<Vec<u8>, Base64DecodeError> {
13 BASE64_STANDARD.decode(input).map_err(|_| Base64DecodeError)
14}
15
16pub fn hex_lower(input: impl AsRef<[u8]>) -> String {
17 hex::encode(input)
18}
19
20pub fn hex_upper(input: impl AsRef<[u8]>) -> String {
21 hex::encode_upper(input)
22}
23
24#[cfg(test)]
25mod tests {
26 use super::*;
27
28 #[test]
29 fn base64_round_trips() {
30 let original = b"apiKey:abc&randomKey:123&signature:deadbeef";
31 let encoded = base64_encode(original);
32 let decoded = base64_decode(&encoded).unwrap();
33 assert_eq!(decoded, original);
34 }
35
36 #[test]
37 fn base64_decode_rejects_garbage() {
38 assert!(base64_decode("not valid base64!!").is_err());
39 }
40
41 #[test]
42 fn hex_case_variants() {
43 let bytes = [0xdeu8, 0xad, 0xbe, 0xef];
44 assert_eq!(hex_lower(bytes), "deadbeef");
45 assert_eq!(hex_upper(bytes), "DEADBEEF");
46 }
47}