Skip to main content

ntex_bytes/
serde.rs

1use serde::{Deserialize, Deserializer, Serialize, Serializer, de};
2use std::{cmp, fmt};
3
4use super::Bytes;
5
6impl Serialize for Bytes {
7    #[inline]
8    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
9    where
10        S: Serializer,
11    {
12        serializer.serialize_bytes(self)
13    }
14}
15
16struct BytesVisitor;
17
18impl<'de> de::Visitor<'de> for BytesVisitor {
19    type Value = Bytes;
20
21    fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
22        formatter.write_str("byte array")
23    }
24
25    #[inline]
26    fn visit_seq<V>(self, mut seq: V) -> Result<Self::Value, V::Error>
27    where
28        V: de::SeqAccess<'de>,
29    {
30        let len = cmp::min(seq.size_hint().unwrap_or(0), 4096);
31        let mut values = Vec::with_capacity(len);
32
33        while let Some(value) = seq.next_element()? {
34            values.push(value);
35        }
36
37        Ok(values.into())
38    }
39
40    #[inline]
41    fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
42    where
43        E: de::Error,
44    {
45        Ok(Bytes::copy_from_slice(v))
46    }
47
48    #[inline]
49    fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
50    where
51        E: de::Error,
52    {
53        Ok(Bytes::from(v))
54    }
55
56    #[inline]
57    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
58    where
59        E: de::Error,
60    {
61        Ok(Bytes::copy_from_slice(v.as_bytes()))
62    }
63
64    #[inline]
65    fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
66    where
67        E: de::Error,
68    {
69        Ok(Bytes::from(v))
70    }
71}
72
73impl<'de> Deserialize<'de> for Bytes {
74    #[inline]
75    fn deserialize<D>(deserializer: D) -> Result<Bytes, D::Error>
76    where
77        D: Deserializer<'de>,
78    {
79        deserializer.deserialize_byte_buf(BytesVisitor)
80    }
81}
82
83#[cfg(test)]
84mod tests {
85    use super::*;
86
87    /// STATEMENT: JSON string deserialization produces matching `Bytes` contents.
88    ///
89    /// HOW:
90    /// - Parse the JSON string `"nice bytes"` as `Bytes` and compare it with `nice bytes`.
91    #[test]
92    fn test_serialize() {
93        let s: Bytes = serde_json::from_str(r#""nice bytes""#).unwrap();
94        assert_eq!(s, "nice bytes");
95        //let s: BytesMut = serde_json::from_str(r#""nice bytes""#).unwrap();
96        //assert_eq!(s, "nice bytes");
97    }
98
99    /// STATEMENT: `Bytes` serializes to a JSON array of numeric byte values.
100    ///
101    /// HOW:
102    /// - Serialize static `nice bytes` and compare the exact decimal byte array string.
103    #[test]
104    fn test_deserialize() {
105        let s = serde_json::to_string(&Bytes::from_static(b"nice bytes")).unwrap();
106        assert_eq!(s, "[110,105,99,101,32,98,121,116,101,115]");
107        //let s = serde_json::to_string(&BytesMut::copy_from_slice(b"nice bytes")).unwrap();
108        //assert_eq!(s, "[110,105,99,101,32,98,121,116,101,115]");
109    }
110
111    /// STATEMENT: `Bytes` deserialization accepts byte buffers, strings, and byte sequences but rejects booleans.
112    ///
113    /// HOW:
114    /// - Deserialize `ab` from byte-buffer, borrowed and owned string, and known- or unknown-length sequence tokens.
115    /// - Check a boolean token reports the expected byte-array type error.
116    #[test]
117    fn test_de_tokens() {
118        use serde_test::{Token, assert_de_tokens, assert_de_tokens_error};
119
120        let b = Bytes::from_static(b"ab");
121        assert_de_tokens(&b, &[Token::ByteBuf(b"ab")]);
122        assert_de_tokens(&b, &[Token::Str("ab")]);
123        assert_de_tokens(&b, &[Token::String("ab")]);
124        assert_de_tokens(
125            &b,
126            &[
127                Token::Seq { len: Some(2) },
128                Token::U8(b'a'),
129                Token::U8(b'b'),
130                Token::SeqEnd,
131            ],
132        );
133        assert_de_tokens(
134            &b,
135            &[
136                Token::Seq { len: None },
137                Token::U8(b'a'),
138                Token::U8(b'b'),
139                Token::SeqEnd,
140            ],
141        );
142        assert_de_tokens_error::<Bytes>(
143            &[Token::Bool(true)],
144            "invalid type: boolean `true`, expected byte array",
145        );
146    }
147
148    /// STATEMENT: JSON serialization and deserialization round-trip `Bytes` contents.
149    ///
150    /// HOW:
151    /// - Serialize static `nice bytes`, deserialize the generated JSON as `Bytes`, and compare with the original.
152    #[test]
153    fn test_json_roundtrip() {
154        let b = Bytes::from_static(b"nice bytes");
155        let s = serde_json::to_string(&b).unwrap();
156        let b2: Bytes = serde_json::from_str(&s).unwrap();
157        assert_eq!(b, b2);
158    }
159}