smart_string/pascal_string/
with_serde.rs

1use core::fmt;
2
3use serde::de::Error;
4use serde::de::Unexpected;
5use serde::de::Visitor;
6use serde::Deserialize;
7use serde::Deserializer;
8use serde::Serialize;
9use serde::Serializer;
10
11use crate::pascal_string::TryFromStrError;
12use crate::PascalString;
13
14struct StringVisitor<const CAPACITY: usize>;
15
16struct StringInPlaceVisitor<'a, const CAPACITY: usize>(&'a mut PascalString<CAPACITY>);
17
18// -------------------------------------------------------------------------------------------------
19
20impl<'de, const CAPACITY: usize> Visitor<'de> for StringVisitor<CAPACITY> {
21    type Value = PascalString<CAPACITY>;
22
23    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
24        write!(
25            formatter,
26            "a string no longer than {CAPACITY} bytes in length",
27        )
28    }
29
30    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
31    where
32        E: Error,
33    {
34        Ok(PascalString::try_from(v)
35            .map_err(|TryFromStrError::TooLong| Error::invalid_length(v.len(), &self))?)
36    }
37
38    fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
39    where
40        E: Error,
41    {
42        match core::str::from_utf8(v) {
43            Ok(s) => self.visit_str(s),
44            Err(_) => Err(Error::invalid_value(Unexpected::Bytes(v), &self)),
45        }
46    }
47}
48
49impl<'a, 'de, const CAPACITY: usize> Visitor<'de> for StringInPlaceVisitor<'a, CAPACITY> {
50    type Value = ();
51
52    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
53        write!(
54            formatter,
55            "a string no longer than {CAPACITY} bytes in length",
56        )
57    }
58
59    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
60    where
61        E: Error,
62    {
63        self.0.clear();
64        self.0
65            .try_push_str(v)
66            .map_err(|TryFromStrError::TooLong| Error::invalid_length(v.len(), &self))?;
67        Ok(())
68    }
69
70    fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
71    where
72        E: Error,
73    {
74        match core::str::from_utf8(v) {
75            Ok(s) => self.visit_str(s),
76            Err(_) => Err(Error::invalid_value(Unexpected::Bytes(v), &self)),
77        }
78    }
79}
80
81// -------------------------------------------------------------------------------------------------
82
83impl<const CAPACITY: usize> Serialize for PascalString<CAPACITY> {
84    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
85        serializer.serialize_str(self)
86    }
87}
88
89impl<'de, const CAPACITY: usize> Deserialize<'de> for PascalString<CAPACITY> {
90    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
91    where
92        D: Deserializer<'de>,
93    {
94        deserializer.deserialize_string(StringVisitor)
95    }
96
97    fn deserialize_in_place<D>(deserializer: D, place: &mut Self) -> Result<(), D::Error>
98    where
99        D: Deserializer<'de>,
100    {
101        deserializer.deserialize_string(StringInPlaceVisitor(place))
102    }
103}