voltaria_sdk/core/
base64_bytes.rs1use base64::{engine::general_purpose::STANDARD, Engine};
18use serde::{self, Deserialize, Deserializer, Serializer};
19
20pub fn serialize<S>(bytes: &Vec<u8>, serializer: S) -> Result<S::Ok, S::Error>
22where
23 S: Serializer,
24{
25 let encoded = STANDARD.encode(bytes);
26 serializer.serialize_str(&encoded)
27}
28
29pub fn deserialize<'de, D>(deserializer: D) -> Result<Vec<u8>, D::Error>
31where
32 D: Deserializer<'de>,
33{
34 let s = String::deserialize(deserializer)?;
35 STANDARD.decode(&s).map_err(serde::de::Error::custom)
36}
37
38pub mod option {
40 use super::*;
41
42 pub fn serialize<S>(bytes: &Option<Vec<u8>>, serializer: S) -> Result<S::Ok, S::Error>
43 where
44 S: Serializer,
45 {
46 match bytes {
47 Some(b) => {
48 let encoded = STANDARD.encode(b);
49 serializer.serialize_some(&encoded)
50 }
51 None => serializer.serialize_none(),
52 }
53 }
54
55 pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<Vec<u8>>, D::Error>
56 where
57 D: Deserializer<'de>,
58 {
59 let opt: Option<String> = Option::deserialize(deserializer)?;
60 match opt {
61 Some(s) => STANDARD
62 .decode(&s)
63 .map(Some)
64 .map_err(serde::de::Error::custom),
65 None => Ok(None),
66 }
67 }
68}
69
70#[cfg(test)]
71mod tests {
72 use super::*;
73 use serde::{Deserialize, Serialize};
74
75 #[derive(Serialize, Deserialize, Debug, PartialEq)]
76 struct TestStruct {
77 #[serde(with = "super")]
78 data: Vec<u8>,
79 }
80
81 #[derive(Serialize, Deserialize, Debug, PartialEq)]
82 struct TestStructOptional {
83 #[serde(default)]
84 #[serde(with = "super::option")]
85 #[serde(skip_serializing_if = "Option::is_none")]
86 data: Option<Vec<u8>>,
87 }
88
89 #[test]
90 fn test_serialize_bytes() {
91 let test = TestStruct {
92 data: b"Hello world!".to_vec(),
93 };
94 let json = serde_json::to_string(&test).unwrap();
95 assert_eq!(json, r#"{"data":"SGVsbG8gd29ybGQh"}"#);
96 }
97
98 #[test]
99 fn test_deserialize_bytes() {
100 let json = r#"{"data":"SGVsbG8gd29ybGQh"}"#;
101 let test: TestStruct = serde_json::from_str(json).unwrap();
102 assert_eq!(test.data, b"Hello world!");
103 }
104
105 #[test]
106 fn test_roundtrip() {
107 let original = TestStruct {
108 data: vec![0, 1, 2, 255, 254, 253],
109 };
110 let json = serde_json::to_string(&original).unwrap();
111 let decoded: TestStruct = serde_json::from_str(&json).unwrap();
112 assert_eq!(original, decoded);
113 }
114
115 #[test]
116 fn test_optional_some() {
117 let test = TestStructOptional {
118 data: Some(b"test".to_vec()),
119 };
120 let json = serde_json::to_string(&test).unwrap();
121 assert_eq!(json, r#"{"data":"dGVzdA=="}"#);
122
123 let decoded: TestStructOptional = serde_json::from_str(&json).unwrap();
124 assert_eq!(test, decoded);
125 }
126
127 #[test]
128 fn test_optional_none() {
129 let test = TestStructOptional { data: None };
130 let json = serde_json::to_string(&test).unwrap();
131 assert_eq!(json, r#"{}"#);
132 }
133
134 #[test]
135 fn test_optional_deserialize_null() {
136 let json = r#"{"data":null}"#;
137 let test: TestStructOptional = serde_json::from_str(json).unwrap();
138 assert_eq!(test.data, None);
139 }
140
141 #[test]
142 fn test_optional_deserialize_missing() {
143 let json = r#"{}"#;
144 let test: TestStructOptional = serde_json::from_str(json).unwrap();
145 assert_eq!(test.data, None);
146 }
147}