faststr_fork/
serde.rs

1use core::fmt;
2
3#[cfg(not(feature = "serde-unsafe"))]
4use serde::de::Unexpected;
5use serde::de::{Deserializer, Error, Visitor};
6
7use crate::FastStr;
8
9// https://github.com/serde-rs/serde/blob/629802f2abfd1a54a6072992888fea7ca5bc209f/serde/src/private/de.rs#L56-L125
10fn fast_str<'de: 'a, 'a, D>(deserializer: D) -> Result<FastStr, D::Error>
11where
12    D: Deserializer<'de>,
13{
14    struct FastStrVisitor;
15
16    impl<'a> Visitor<'a> for FastStrVisitor {
17        type Value = FastStr;
18
19        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
20            formatter.write_str("a string")
21        }
22
23        fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
24        where
25            E: Error,
26        {
27            Ok(FastStr::new(v))
28        }
29
30        fn visit_borrowed_str<E>(self, v: &'a str) -> Result<Self::Value, E>
31        where
32            E: Error,
33        {
34            Ok(FastStr::new(v))
35        }
36
37        fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
38        where
39            E: Error,
40        {
41            Ok(FastStr::from(v))
42        }
43
44        fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
45        where
46            E: Error,
47        {
48            #[cfg(feature = "serde-unsafe")]
49            {
50                Ok(unsafe { FastStr::new_u8_slice_unchecked(v) })
51            }
52            #[cfg(not(feature = "serde-unsafe"))]
53            match FastStr::new_u8_slice(v) {
54                Ok(s) => Ok(s),
55                Err(_) => Err(Error::invalid_value(Unexpected::Bytes(v), &self)),
56            }
57        }
58
59        fn visit_borrowed_bytes<E>(self, v: &'a [u8]) -> Result<Self::Value, E>
60        where
61            E: Error,
62        {
63            #[cfg(feature = "serde-unsafe")]
64            {
65                Ok(unsafe { FastStr::new_u8_slice_unchecked(v) })
66            }
67            #[cfg(not(feature = "serde-unsafe"))]
68            match FastStr::new_u8_slice(v) {
69                Ok(s) => Ok(s),
70                Err(_) => Err(Error::invalid_value(Unexpected::Bytes(v), &self)),
71            }
72        }
73
74        fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
75        where
76            E: Error,
77        {
78            #[cfg(not(feature = "serde-unsafe"))]
79            simdutf8::basic::from_utf8(&v)
80                .map_err(|_| Error::invalid_value(Unexpected::Bytes(&v), &self))?;
81            // Safety: we have checked that v is valid utf-8
82            Ok(unsafe { FastStr::from_vec_u8_unchecked(v) })
83        }
84    }
85
86    deserializer.deserialize_string(FastStrVisitor)
87}
88
89impl serde::Serialize for FastStr {
90    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
91    where
92        S: serde::Serializer,
93    {
94        self.as_str().serialize(serializer)
95    }
96}
97
98impl<'de> serde::Deserialize<'de> for FastStr {
99    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
100    where
101        D: serde::Deserializer<'de>,
102    {
103        fast_str(deserializer)
104    }
105}