1use alloc::{string::String, vec::Vec};
2use base64::{engine::GeneralPurpose, Engine};
3
4use crate::StdResult;
5
6const B64_ENGINE: GeneralPurpose = GeneralPurpose::new(
11 &base64::alphabet::STANDARD,
12 base64::engine::GeneralPurposeConfig::new()
13 .with_decode_padding_mode(base64::engine::DecodePaddingMode::Indifferent),
14);
15
16pub fn from_base64<I>(input: I) -> StdResult<Vec<u8>>
18where
19 I: AsRef<[u8]>,
20{
21 Ok(B64_ENGINE.decode(input)?)
22}
23
24pub fn to_base64<I>(input: I) -> String
26where
27 I: AsRef<[u8]>,
28{
29 B64_ENGINE.encode(input)
30}
31
32pub fn from_hex<I>(input: I) -> StdResult<Vec<u8>>
34where
35 I: AsRef<[u8]>,
36{
37 Ok(hex::decode(input)?)
38}
39
40pub fn to_hex<I>(input: I) -> String
42where
43 I: AsRef<[u8]>,
44{
45 hex::encode(input)
46}
47
48#[cfg(test)]
49mod test {
50 use crate::{from_base64, from_hex, to_base64, to_hex};
51
52 const BASE64_FOOBAR: &str = "Zm9vYmFy"; const HEX_FOOBAR: &str = "666f6f626172"; #[test]
56 fn from_base64_works() {
57 let decoded = from_base64(BASE64_FOOBAR).unwrap();
58 assert_eq!(decoded, b"foobar");
59 }
60
61 #[test]
62 fn to_base64_works() {
63 let encoded = to_base64("foobar");
64 assert_eq!(encoded, BASE64_FOOBAR);
65 }
66
67 #[test]
68 fn base64_roundtrip_works() {
69 let decoded = from_base64(BASE64_FOOBAR).unwrap();
70 assert_eq!(decoded, b"foobar");
71 let encoded = to_base64(decoded);
72 assert_eq!(encoded, BASE64_FOOBAR);
73 }
74
75 #[test]
76 fn from_hex_works() {
77 let decoded = from_hex(HEX_FOOBAR).unwrap();
78 assert_eq!(decoded, b"foobar");
79 }
80
81 #[test]
82 fn to_hex_works() {
83 let encoded = to_hex("foobar");
84 assert_eq!(encoded, HEX_FOOBAR);
85 }
86
87 #[test]
88 fn hex_roundtrip_works() {
89 let decoded = from_hex(HEX_FOOBAR).unwrap();
90 assert_eq!(decoded, b"foobar");
91 let encoded = to_hex(decoded);
92 assert_eq!(encoded, HEX_FOOBAR);
93 }
94}