smartstring/
serde.rs

1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at http://mozilla.org/MPL/2.0/.
4
5use crate::{SmartString, SmartStringMode};
6use alloc::string::String;
7use core::{fmt, marker::PhantomData};
8
9use serde::{
10    de::{Error, Visitor},
11    Deserialize, Deserializer, Serialize, Serializer,
12};
13
14impl<T: SmartStringMode> Serialize for SmartString<T> {
15    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
16    where
17        S: Serializer,
18    {
19        serializer.serialize_str(self)
20    }
21}
22
23impl<'de, T: SmartStringMode> Deserialize<'de> for SmartString<T> {
24    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
25    where
26        D: Deserializer<'de>,
27    {
28        deserializer
29            .deserialize_string(SmartStringVisitor(PhantomData))
30            .map(SmartString::from)
31    }
32}
33
34struct SmartStringVisitor<T: SmartStringMode>(PhantomData<*const T>);
35
36impl<'de, T: SmartStringMode> Visitor<'de> for SmartStringVisitor<T> {
37    type Value = SmartString<T>;
38
39    fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
40        formatter.write_str("a string")
41    }
42
43    fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
44    where
45        E: Error,
46    {
47        Ok(SmartString::from(v))
48    }
49
50    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
51    where
52        E: Error,
53    {
54        Ok(SmartString::from(v))
55    }
56}
57
58#[cfg(test)]
59mod test {
60    use super::*;
61    use crate::Compact;
62
63    #[test]
64    fn test_ser_de() {
65        use serde_test::{assert_tokens, Token};
66
67        let strings = [
68            "",
69            "small test",
70            "longer than inline string for serde testing",
71        ];
72
73        for &string in strings.iter() {
74            let value = SmartString::<Compact>::from(string);
75            assert_tokens(&value, &[Token::String(string)]);
76        }
77    }
78}