agentguard_core/
chain_secret.rs1use base64::Engine as _;
16
17pub fn decode(bytes: &[u8]) -> Option<Vec<u8>> {
25 if bytes.is_empty() {
26 return None;
27 }
28 if let Ok(s) = std::str::from_utf8(bytes) {
29 let s = s.trim();
30 if s.len() == 64 && s.chars().all(|c| c.is_ascii_hexdigit()) {
31 if let Ok(b) = hex::decode(s) {
32 return Some(b);
33 }
34 }
35 if let Ok(b) = base64::engine::general_purpose::STANDARD.decode(s) {
36 return Some(b);
37 }
38 }
39 Some(bytes.to_vec())
40}
41
42#[cfg(test)]
43mod tests {
44 use super::*;
45
46 #[test]
47 fn empty_is_none() {
48 assert_eq!(decode(b""), None);
49 }
50
51 #[test]
52 fn hex_64_chars() {
53 let hex = "0".repeat(64);
54 let out = decode(hex.as_bytes()).unwrap();
55 assert_eq!(out.len(), 32);
56 assert!(out.iter().all(|&b| b == 0));
57 }
58
59 #[test]
60 fn base64_padded() {
61 let raw = [42u8; 32];
62 let b64 = base64::engine::general_purpose::STANDARD.encode(raw);
63 let out = decode(b64.as_bytes()).unwrap();
64 assert_eq!(out, raw);
65 }
66
67 #[test]
68 fn raw_bytes_passthrough() {
69 let raw = [1u8, 2, 3, 4];
70 let out = decode(&raw).unwrap();
71 assert_eq!(out, raw);
72 }
73
74 #[test]
75 fn trims_whitespace() {
76 let raw = [7u8; 32];
77 let b64 = format!(
78 " {} ",
79 base64::engine::general_purpose::STANDARD.encode(raw)
80 );
81 let out = decode(b64.as_bytes()).unwrap();
82 assert_eq!(out, raw);
83 }
84}