mountpoint_s3_client/
checksums.rs1pub use mountpoint_s3_crt::checksums::crc32::{self, Crc32};
3pub use mountpoint_s3_crt::checksums::crc32c::{self, Crc32c};
4pub use mountpoint_s3_crt::checksums::crc64nvme::{self, Crc64nvme};
5pub use mountpoint_s3_crt::checksums::sha1::{self, Sha1};
6pub use mountpoint_s3_crt::checksums::sha256::{self, Sha256};
7
8use base64ct::Base64;
9use base64ct::Encoding;
10use thiserror::Error;
11
12pub fn crc64nvme_to_base64(checksum: &Crc64nvme) -> String {
14 Base64::encode_string(&checksum.value().to_be_bytes())
15}
16
17pub fn crc64nvme_from_base64(base64_str: &str) -> Result<Crc64nvme, ParseError> {
19 let mut dec_buf = [0u8; std::mem::size_of::<u64>()];
20 let _ = Base64::decode(base64_str, &mut dec_buf)?;
21 Ok(Crc64nvme::new(u64::from_be_bytes(dec_buf)))
22}
23
24pub fn crc32c_to_base64(checksum: &Crc32c) -> String {
26 Base64::encode_string(&checksum.value().to_be_bytes())
27}
28
29pub fn crc32c_from_base64(base64_str: &str) -> Result<Crc32c, ParseError> {
31 let mut dec_buf = [0u8; std::mem::size_of::<u32>()];
32 let _ = Base64::decode(base64_str, &mut dec_buf)?;
33 Ok(Crc32c::new(u32::from_be_bytes(dec_buf)))
34}
35
36pub fn crc32_to_base64(checksum: &Crc32) -> String {
38 Base64::encode_string(&checksum.value().to_be_bytes())
39}
40
41pub fn crc32_from_base64(base64_str: &str) -> Result<Crc32, ParseError> {
43 let mut dec_buf = [0u8; std::mem::size_of::<u32>()];
44 let _ = Base64::decode(base64_str, &mut dec_buf)?;
45 Ok(Crc32::new(u32::from_be_bytes(dec_buf)))
46}
47
48pub fn sha1_to_base64(checksum: &Sha1) -> String {
50 Base64::encode_string(checksum.value())
51}
52
53pub fn sha256_to_base64(checksum: &Sha256) -> String {
55 Base64::encode_string(checksum.value())
56}
57
58#[derive(Error, Debug)]
60pub enum ParseError {
61 #[error("Failed to parse base64 encoding")]
63 Base64ParseError(#[from] base64ct::Error),
64}
65
66#[cfg(test)]
67mod tests {
68 use super::*;
69 use test_case::test_case;
70
71 #[test]
72 fn test_crc64nvme_to_base64() {
73 let crc = Crc64nvme::new(0xAE8B14860A799888);
74 let base64 = crc64nvme_to_base64(&crc);
75 assert_eq!(&base64, "rosUhgp5mIg=");
76 }
77
78 #[test]
79 fn test_crc64nvme_from_base64() {
80 let base64 = "rosUhgp5mIg=";
81 let crc = crc64nvme_from_base64(base64).expect("parsing should succeeed");
82 assert_eq!(crc.value(), 0xAE8B14860A799888);
83 }
84
85 #[test]
86 fn test_crc32c_to_base64() {
87 let crc = Crc32c::new(1234);
88 let base64 = crc32c_to_base64(&crc);
89 assert_eq!(&base64, "AAAE0g==");
90 }
91
92 #[test]
93 fn test_crc32c_from_base64() {
94 let base64 = "AAAE0g==";
95 let crc = crc32c_from_base64(base64).expect("parsing should succeeed");
96 assert_eq!(crc.value(), 1234);
97 }
98
99 #[test_case("AAA")]
100 #[test_case("AAAE0g")]
101 #[test_case("AAAE0gAA==")]
102 fn test_crc32c_from_base64_error(invalid_base64: &str) {
103 let err = crc32c_from_base64(invalid_base64).expect_err("parsing should fail");
104 assert!(matches!(err, ParseError::Base64ParseError(_)));
105 }
106
107 #[test]
108 fn test_crc32_to_base64() {
109 let crc = Crc32::new(1234);
110 let base64 = crc32_to_base64(&crc);
111 assert_eq!(&base64, "AAAE0g==");
112 }
113
114 #[test]
115 fn test_crc32_from_base64() {
116 let base64 = "AAAE0g==";
117 let crc = crc32_from_base64(base64).expect("parsing should succeeed");
118 assert_eq!(crc.value(), 1234);
119 }
120
121 #[test_case("AAA")]
122 #[test_case("AAAE0g")]
123 #[test_case("AAAE0gAA==")]
124 fn test_crc32_from_base64_error(invalid_base64: &str) {
125 let err = crc32_from_base64(invalid_base64).expect_err("parsing should fail");
126 assert!(matches!(err, ParseError::Base64ParseError(_)));
127 }
128
129 #[test]
130 fn test_sha1_to_base64() {
131 let sha1 = Sha1::new([
132 247, 195, 188, 29, 128, 142, 4, 115, 42, 223, 103, 153, 101, 204, 195, 76, 167, 174, 52, 65,
133 ]);
134 let base64 = sha1_to_base64(&sha1);
135 assert_eq!(&base64, "98O8HYCOBHMq32eZZczDTKeuNEE=");
136 }
137
138 #[test]
139 fn test_sha256_to_base64() {
140 let sha256 = Sha256::new([
141 21, 226, 176, 211, 195, 56, 145, 235, 176, 241, 239, 96, 158, 196, 25, 66, 12, 32, 227, 32, 206, 148, 198,
142 95, 188, 140, 51, 18, 68, 142, 178, 37,
143 ]);
144 let base64 = sha256_to_base64(&sha256);
145 assert_eq!(&base64, "FeKw08M4keuw8e9gnsQZQgwg4yDOlMZfvIwzEkSOsiU=");
146 }
147}