1 use std::fmt;
2 
3 use serde::de::{Error, Unexpected, Visitor};
4 use serde::{Deserialize, Deserializer, Serialize, Serializer};
5 
6 use ascii_str::AsciiStr;
7 
8 impl Serialize for AsciiStr {
9     #[inline]
10     fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
11         serializer.serialize_str(self.as_str())
12     }
13 }
14 
15 struct AsciiStrVisitor;
16 
17 impl<'a> Visitor<'a> for AsciiStrVisitor {
18     type Value = &'a AsciiStr;
19 
20     fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
21         f.write_str("a borrowed ascii string")
22     }
23 
24     fn visit_borrowed_str<E: Error>(self, v: &'a str) -> Result<Self::Value, E> {
25         AsciiStr::from_ascii(v.as_bytes())
26             .map_err(|_| Error::invalid_value(Unexpected::Str(v), &self))
27     }
28 
29     fn visit_borrowed_bytes<E: Error>(self, v: &'a [u8]) -> Result<Self::Value, E> {
30         AsciiStr::from_ascii(v).map_err(|_| Error::invalid_value(Unexpected::Bytes(v), &self))
31     }
32 }
33 
34 impl<'de: 'a, 'a> Deserialize<'de> for &'a AsciiStr {
35     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
36     where
37         D: Deserializer<'de>,
38     {
39         deserializer.deserialize_str(AsciiStrVisitor)
40     }
41 }
42 
43 #[cfg(test)]
44 mod tests {
45     use super::*;
46 
47     #[cfg(feature = "serde_test")]
48     const ASCII: &str = "Francais";
49     #[cfg(feature = "serde_test")]
50     const UNICODE: &str = "Français";
51 
52     #[test]
53     fn basic() {
54         fn assert_serialize<T: Serialize>() {}
55         assert_serialize::<&AsciiStr>();
56         fn assert_deserialize<'de, T: Deserialize<'de>>() {}
57         assert_deserialize::<&AsciiStr>();
58     }
59 
60     #[test]
61     #[cfg(feature = "serde_test")]
62     fn serialize() {
63         use serde_test::{assert_tokens, Token};
64         let ascii_str = AsciiStr::from_ascii(ASCII).unwrap();
65         assert_tokens(&ascii_str, &[Token::BorrowedStr(ASCII)]);
66     }
67 
68     #[test]
69     #[cfg(feature = "serde_test")]
70     fn deserialize() {
71         use serde_test::{assert_de_tokens, assert_de_tokens_error, Token};
satamv_init(void)72         let ascii_str = AsciiStr::from_ascii(ASCII).unwrap();
73         assert_de_tokens(&ascii_str, &[Token::BorrowedBytes(ASCII.as_bytes())]);
74         assert_de_tokens_error::<&AsciiStr>(
75             &[Token::BorrowedStr(UNICODE)],
76             "invalid value: string \"Français\", expected a borrowed ascii string",
77         );
78     }
79 }
80