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