scuffle_bytes_util/cow/string/
serde.rs

1use super::StringCow;
2
3impl serde::Serialize for StringCow<'_> {
4    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
5    where
6        S: serde::Serializer,
7    {
8        serializer.serialize_str(self.as_str())
9    }
10}
11
12impl<'de> serde::Deserialize<'de> for StringCow<'de> {
13    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
14    where
15        D: serde::Deserializer<'de>,
16    {
17        struct StringCowVisitor;
18
19        impl<'de> serde::de::Visitor<'de> for StringCowVisitor {
20            type Value = StringCow<'de>;
21
22            fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
23                formatter.write_str("a string")
24            }
25
26            fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
27            where
28                E: serde::de::Error,
29            {
30                Ok(StringCow::from_ref(v))
31            }
32
33            fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
34            where
35                E: serde::de::Error,
36            {
37                Ok(StringCow::from_string(v))
38            }
39
40            fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
41            where
42                E: serde::de::Error,
43            {
44                Ok(StringCow::from_string(v.to_string()))
45            }
46        }
47
48        deserializer.deserialize_any(StringCowVisitor)
49    }
50}
51
52impl<'de, E> serde::de::IntoDeserializer<'de, E> for StringCow<'de>
53where
54    E: serde::de::Error,
55{
56    type Deserializer = StringCowDeserializer<'de, E>;
57
58    fn into_deserializer(self) -> Self::Deserializer {
59        StringCowDeserializer::<E>::new(self)
60    }
61}
62
63/// A deserializer for [`StringCow`].
64pub struct StringCowDeserializer<'a, E> {
65    cow: StringCow<'a>,
66    _marker: std::marker::PhantomData<E>,
67}
68
69impl<'a, E> StringCowDeserializer<'a, E> {
70    /// Creates a new [`StringCowDeserializer`].
71    pub fn new(cow: StringCow<'a>) -> Self {
72        StringCowDeserializer {
73            cow,
74            _marker: std::marker::PhantomData,
75        }
76    }
77}
78
79impl<'de, E> serde::de::Deserializer<'de> for StringCowDeserializer<'de, E>
80where
81    E: serde::de::Error,
82{
83    type Error = E;
84
85    serde::forward_to_deserialize_any! {
86        bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
87        bytes byte_buf option unit unit_struct newtype_struct seq tuple
88        tuple_struct map struct enum identifier ignored_any
89    }
90
91    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
92    where
93        V: serde::de::Visitor<'de>,
94    {
95        match self.cow {
96            StringCow::Ref(slice) => visitor.visit_borrowed_str(slice),
97            StringCow::StaticRef(slice) => visitor.visit_borrowed_str(slice),
98            StringCow::String(string) => visitor.visit_string(string),
99            StringCow::Bytes(bytes) => visitor.visit_str(&bytes),
100        }
101    }
102}
103
104#[cfg(test)]
105#[cfg_attr(all(test, coverage_nightly), coverage(off))]
106mod tests {
107    use std::fmt::Display;
108
109    use serde::ser::Impossible;
110    use serde::{Deserialize, Serialize};
111
112    use crate::StringCow;
113
114    #[test]
115    fn serialize() {
116        #[derive(Debug)]
117        struct TestError;
118
119        impl Display for TestError {
120            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
121                write!(f, "Test error")
122            }
123        }
124
125        impl std::error::Error for TestError {}
126
127        impl serde::ser::Error for TestError {
128            fn custom<T: std::fmt::Display>(msg: T) -> Self {
129                panic!("{}", msg)
130            }
131        }
132
133        struct TestSerializer;
134
135        impl serde::Serializer for TestSerializer {
136            type Error = TestError;
137            type Ok = ();
138            type SerializeMap = Impossible<(), Self::Error>;
139            type SerializeSeq = Impossible<(), Self::Error>;
140            type SerializeStruct = Impossible<(), Self::Error>;
141            type SerializeStructVariant = Impossible<(), Self::Error>;
142            type SerializeTuple = Impossible<(), Self::Error>;
143            type SerializeTupleStruct = Impossible<(), Self::Error>;
144            type SerializeTupleVariant = Impossible<(), Self::Error>;
145
146            fn serialize_bool(self, _v: bool) -> Result<Self::Ok, Self::Error> {
147                panic!("StringCow must be serialized as str")
148            }
149
150            fn serialize_i8(self, _v: i8) -> Result<Self::Ok, Self::Error> {
151                panic!("StringCow must be serialized as str")
152            }
153
154            fn serialize_i16(self, _v: i16) -> Result<Self::Ok, Self::Error> {
155                panic!("StringCow must be serialized as str")
156            }
157
158            fn serialize_i32(self, _v: i32) -> Result<Self::Ok, Self::Error> {
159                panic!("StringCow must be serialized as str")
160            }
161
162            fn serialize_i64(self, _v: i64) -> Result<Self::Ok, Self::Error> {
163                panic!("StringCow must be serialized as str")
164            }
165
166            fn serialize_u8(self, _v: u8) -> Result<Self::Ok, Self::Error> {
167                panic!("StringCow must be serialized as str")
168            }
169
170            fn serialize_u16(self, _v: u16) -> Result<Self::Ok, Self::Error> {
171                panic!("StringCow must be serialized as str")
172            }
173
174            fn serialize_u32(self, _v: u32) -> Result<Self::Ok, Self::Error> {
175                panic!("StringCow must be serialized as str")
176            }
177
178            fn serialize_u64(self, _v: u64) -> Result<Self::Ok, Self::Error> {
179                panic!("StringCow must be serialized as str")
180            }
181
182            fn serialize_f32(self, _v: f32) -> Result<Self::Ok, Self::Error> {
183                panic!("StringCow must be serialized as str")
184            }
185
186            fn serialize_f64(self, _v: f64) -> Result<Self::Ok, Self::Error> {
187                panic!("StringCow must be serialized as str")
188            }
189
190            fn serialize_char(self, _v: char) -> Result<Self::Ok, Self::Error> {
191                panic!("StringCow must be serialized as str")
192            }
193
194            fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error> {
195                assert_eq!(v, "hello");
196                Ok(())
197            }
198
199            fn serialize_bytes(self, _v: &[u8]) -> Result<Self::Ok, Self::Error> {
200                panic!("StringCow must be serialized as str")
201            }
202
203            fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
204                panic!("StringCow must be serialized as str")
205            }
206
207            fn serialize_some<T>(self, _value: &T) -> Result<Self::Ok, Self::Error>
208            where
209                T: serde::Serialize + ?Sized,
210            {
211                panic!("StringCow must be serialized as str")
212            }
213
214            fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
215                panic!("StringCow must be serialized as str")
216            }
217
218            fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> {
219                panic!("StringCow must be serialized as str")
220            }
221
222            fn serialize_unit_variant(
223                self,
224                _name: &'static str,
225                _variant_index: u32,
226                _variant: &'static str,
227            ) -> Result<Self::Ok, Self::Error> {
228                panic!("StringCow must be serialized as str")
229            }
230
231            fn serialize_newtype_variant<T>(
232                self,
233                _name: &'static str,
234                _variant_index: u32,
235                _variant: &'static str,
236                _value: &T,
237            ) -> Result<Self::Ok, Self::Error>
238            where
239                T: serde::Serialize + ?Sized,
240            {
241                panic!("StringCow must be serialized as str")
242            }
243
244            fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
245                panic!("StringCow must be serialized as str")
246            }
247
248            fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Self::Error> {
249                panic!("StringCow must be serialized as str")
250            }
251
252            fn serialize_tuple_struct(
253                self,
254                _name: &'static str,
255                _len: usize,
256            ) -> Result<Self::SerializeTupleStruct, Self::Error> {
257                panic!("StringCow must be serialized as str")
258            }
259
260            fn serialize_tuple_variant(
261                self,
262                _name: &'static str,
263                _variant_index: u32,
264                _variant: &'static str,
265                _len: usize,
266            ) -> Result<Self::SerializeTupleVariant, Self::Error> {
267                panic!("StringCow must be serialized as str")
268            }
269
270            fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
271                panic!("StringCow must be serialized as str")
272            }
273
274            fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct, Self::Error> {
275                panic!("StringCow must be serialized as str")
276            }
277
278            fn serialize_struct_variant(
279                self,
280                _name: &'static str,
281                _variant_index: u32,
282                _variant: &'static str,
283                _len: usize,
284            ) -> Result<Self::SerializeStructVariant, Self::Error> {
285                panic!("StringCow must be serialized as str")
286            }
287
288            fn serialize_newtype_struct<T>(self, _name: &'static str, _value: &T) -> Result<Self::Ok, Self::Error>
289            where
290                T: ?Sized + serde::Serialize,
291            {
292                panic!("StringCow must be serialized as str")
293            }
294        }
295
296        let cow = StringCow::from_ref("hello");
297        let serializer = TestSerializer;
298        cow.serialize(serializer).expect("serialization failed");
299    }
300
301    #[test]
302    fn deserialize() {
303        #[derive(Debug)]
304        struct TestError;
305
306        impl Display for TestError {
307            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
308                write!(f, "Test error")
309            }
310        }
311
312        impl std::error::Error for TestError {}
313
314        impl serde::de::Error for TestError {
315            fn custom<T: std::fmt::Display>(msg: T) -> Self {
316                assert_eq!(msg.to_string(), "invalid type: Option value, expected a string");
317                Self
318            }
319        }
320
321        enum Mode {
322            Str,
323            String,
324            BorrowedStr,
325            None,
326        }
327
328        struct TestDeserializer {
329            mode: Mode,
330        }
331
332        impl<'de> serde::Deserializer<'de> for TestDeserializer {
333            type Error = TestError;
334
335            serde::forward_to_deserialize_any! {
336                bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes byte_buf
337                option unit unit_struct newtype_struct seq tuple tuple_struct
338                map struct enum identifier ignored_any
339            }
340
341            fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
342            where
343                V: serde::de::Visitor<'de>,
344            {
345                match self.mode {
346                    Mode::Str => visitor.visit_str("hello"),
347                    Mode::String => visitor.visit_string("hello".to_owned()),
348                    Mode::BorrowedStr => visitor.visit_borrowed_str("hello"),
349                    Mode::None => visitor.visit_none(),
350                }
351            }
352        }
353
354        fn test_de(de: TestDeserializer) {
355            let cow = StringCow::deserialize(de).expect("deserialization failed");
356            assert_eq!(cow.as_str(), "hello");
357        }
358
359        test_de(TestDeserializer { mode: Mode::Str });
360        test_de(TestDeserializer { mode: Mode::String });
361        test_de(TestDeserializer { mode: Mode::BorrowedStr });
362
363        StringCow::deserialize(TestDeserializer { mode: Mode::None }).expect_err("deserialization should fail");
364    }
365}