dpp/serialization/
serde_bytes_var.rs1use base64::prelude::BASE64_STANDARD;
15use base64::Engine;
16use serde::de::{self, SeqAccess, Visitor};
17use serde::{Deserializer, Serializer};
18use std::fmt;
19
20pub fn serialize<S: Serializer>(bytes: &Vec<u8>, serializer: S) -> Result<S::Ok, S::Error> {
21 if serializer.is_human_readable() {
22 serializer.serialize_str(&BASE64_STANDARD.encode(bytes))
23 } else {
24 serializer.serialize_bytes(bytes)
25 }
26}
27
28pub fn deserialize<'de, D: Deserializer<'de>>(deserializer: D) -> Result<Vec<u8>, D::Error> {
29 struct AnyShapeVisitor;
37
38 impl<'de> Visitor<'de> for AnyShapeVisitor {
39 type Value = Vec<u8>;
40
41 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
42 f.write_str("bytes, sequence of u8, or base64-encoded string")
43 }
44
45 fn visit_bytes<E: de::Error>(self, v: &[u8]) -> Result<Self::Value, E> {
46 Ok(v.to_vec())
47 }
48
49 fn visit_byte_buf<E: de::Error>(self, v: Vec<u8>) -> Result<Self::Value, E> {
50 Ok(v)
51 }
52
53 fn visit_str<E: de::Error>(self, v: &str) -> Result<Self::Value, E> {
54 BASE64_STANDARD
55 .decode(v)
56 .map_err(|e| E::custom(format!("expected base64 for bytes: {}", e)))
57 }
58
59 fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
60 let mut bytes = Vec::with_capacity(seq.size_hint().unwrap_or(0));
61 while let Some(b) = seq.next_element::<u8>()? {
62 bytes.push(b);
63 }
64 Ok(bytes)
65 }
66 }
67
68 if deserializer.is_human_readable() {
69 deserializer.deserialize_any(AnyShapeVisitor)
73 } else {
74 deserializer.deserialize_byte_buf(AnyShapeVisitor)
76 }
77}
78
79#[cfg(test)]
80mod tests {
81 use base64::prelude::BASE64_STANDARD;
82 use base64::Engine;
83 use serde::{Deserialize, Serialize};
84
85 #[derive(Serialize, Deserialize, PartialEq, Debug)]
86 struct Wrap(#[serde(with = "super")] Vec<u8>);
87
88 #[test]
89 fn json_emits_base64_string() {
90 let original = Wrap(vec![0xde, 0xad, 0xbe, 0xef]);
91 let value = serde_json::to_value(&original).expect("serialize");
92 assert_eq!(
93 value,
94 serde_json::json!(BASE64_STANDARD.encode([0xde, 0xad, 0xbe, 0xef]))
95 );
96
97 let restored: Wrap = serde_json::from_value(value).expect("deserialize");
98 assert_eq!(original, restored);
99 }
100
101 #[test]
102 fn empty_vec_round_trips() {
103 let original = Wrap(Vec::new());
104 let value = serde_json::to_value(&original).expect("serialize empty");
105 assert_eq!(value, serde_json::json!(""));
106 let restored: Wrap = serde_json::from_value(value).expect("deserialize empty");
107 assert_eq!(original, restored);
108 }
109
110 #[test]
111 fn binary_round_trip_uses_raw_bytes() {
112 let original = Wrap(vec![1, 2, 3, 4, 5]);
113 let bytes = bincode::serde::encode_to_vec(&original, bincode::config::standard())
114 .expect("bincode encode");
115 let (restored, _): (Wrap, usize) =
116 bincode::serde::decode_from_slice(&bytes, bincode::config::standard())
117 .expect("bincode decode");
118 assert_eq!(original, restored);
119 }
120}