reifydb_type/value/blob/
base64.rs1use super::Blob;
5use crate::{
6 error::{Error, diagnostic::blob},
7 fragment::Fragment,
8 util::base64::engine::general_purpose,
9};
10
11impl Blob {
12 pub fn from_b64(fragment: Fragment) -> Result<Self, Error> {
13 let fragment = fragment;
14 let b64_str = fragment.text();
15 match general_purpose::STANDARD.decode(b64_str) {
17 Ok(bytes) => Ok(Blob::new(bytes)),
18 Err(_) => {
19 match general_purpose::STANDARD_NO_PAD.decode(b64_str) {
21 Ok(bytes) => Ok(Blob::new(bytes)),
22 Err(_) => Err(Error(blob::invalid_base64_string(fragment))),
23 }
24 }
25 }
26 }
27
28 pub fn from_b64url(fragment: Fragment) -> Result<Self, Error> {
29 let fragment = fragment;
30 let b64url_str = fragment.text();
31 match general_purpose::URL_SAFE_NO_PAD.decode(b64url_str) {
32 Ok(bytes) => Ok(Blob::new(bytes)),
33 Err(_) => Err(Error(blob::invalid_base64url_string(fragment))),
34 }
35 }
36
37 pub fn to_b64(&self) -> String {
38 general_purpose::STANDARD.encode(self.as_bytes())
39 }
40
41 pub fn to_b64url(&self) -> String {
42 general_purpose::URL_SAFE_NO_PAD.encode(self.as_bytes())
43 }
44}
45
46#[cfg(test)]
47pub mod tests {
48 use super::*;
49 use crate::fragment::Fragment;
50
51 #[test]
52 fn test_from_b64() {
53 let blob = Blob::from_b64(Fragment::testing("SGVsbG8=")).unwrap();
54 assert_eq!(blob.as_bytes(), b"Hello");
55 }
56
57 #[test]
58 fn test_from_b64_no_padding() {
59 let blob = Blob::from_b64(Fragment::testing("SGVsbG8")).unwrap();
60 assert_eq!(blob.as_bytes(), b"Hello");
61 }
62
63 #[test]
64 fn test_from_b64_empty() {
65 let blob = Blob::from_b64(Fragment::testing("")).unwrap();
66 assert_eq!(blob.as_bytes(), b"");
67 }
68
69 #[test]
70 fn test_from_b64_invalid() {
71 let result = Blob::from_b64(Fragment::testing("!!!invalid!!!"));
72 assert!(result.is_err());
73 }
74
75 #[test]
76 fn test_from_b64url() {
77 let blob = Blob::from_b64url(Fragment::testing("SGVsbG8")).unwrap();
78 assert_eq!(blob.as_bytes(), b"Hello");
79 }
80
81 #[test]
82 fn test_from_b64url_invalid() {
83 let result = Blob::from_b64url(Fragment::testing("SGVsbG8=")); assert!(result.is_err());
85 }
86
87 #[test]
88 fn test_to_b64() {
89 let blob = Blob::new(b"Hello".to_vec());
90 assert_eq!(blob.to_b64(), "SGVsbG8=");
91 }
92
93 #[test]
94 fn test_to_b64url() {
95 let blob = Blob::new(b"Hello".to_vec());
96 assert_eq!(blob.to_b64url(), "SGVsbG8");
97 }
98
99 #[test]
100 fn test_b64_roundtrip() {
101 let original = b"Hello, World! \x00\x01\x02\xFF";
102 let blob = Blob::new(original.to_vec());
103 let b64_str = blob.to_b64();
104 let decoded = Blob::from_b64(Fragment::testing(&b64_str)).unwrap();
105 assert_eq!(decoded.as_bytes(), original);
106 }
107
108 #[test]
109 fn test_b64url_roundtrip() {
110 let original = b"Hello, World! \x00\x01\x02\xFF";
111 let blob = Blob::new(original.to_vec());
112 let b64url_str = blob.to_b64url();
113 let decoded = Blob::from_b64url(Fragment::testing(&b64url_str)).unwrap();
114 assert_eq!(decoded.as_bytes(), original);
115 }
116}