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