icu_locale_core/
serde.rs

1// This file is part of ICU4X. For terms of use, please see the file
2// called LICENSE at the top level of the ICU4X source tree
3// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
4
5use crate::LanguageIdentifier;
6use serde::{Deserialize, Deserializer, Serialize, Serializer};
7
8impl Serialize for LanguageIdentifier {
9    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
10    where
11        S: Serializer,
12    {
13        serializer.serialize_str(&self.to_string())
14    }
15}
16
17impl<'de> Deserialize<'de> for LanguageIdentifier {
18    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
19    where
20        D: Deserializer<'de>,
21    {
22        struct LanguageIdentifierVisitor;
23
24        impl serde::de::Visitor<'_> for LanguageIdentifierVisitor {
25            type Value = LanguageIdentifier;
26
27            fn expecting(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
28                write!(formatter, "a valid Unicode Language Identifier")
29            }
30
31            fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
32            where
33                E: serde::de::Error,
34            {
35                s.parse::<LanguageIdentifier>()
36                    .map_err(serde::de::Error::custom)
37            }
38        }
39
40        deserializer.deserialize_string(LanguageIdentifierVisitor)
41    }
42}
43
44#[test]
45fn json() {
46    use crate::langid;
47    use crate::subtags::{Language, Region, Script};
48
49    assert_eq!(
50        serde_json::to_string(&langid!("en-US")).unwrap(),
51        r#""en-US""#
52    );
53    assert_eq!(
54        serde_json::from_str::<LanguageIdentifier>(r#""en-US""#).unwrap(),
55        langid!("en-US")
56    );
57    assert!(serde_json::from_str::<LanguageIdentifier>(r#""2Xs""#).is_err());
58
59    assert_eq!(
60        serde_json::to_string(&"fr".parse::<Language>().unwrap()).unwrap(),
61        r#""fr""#
62    );
63    assert_eq!(
64        serde_json::from_str::<Language>(r#""fr""#).unwrap(),
65        "fr".parse::<Language>().unwrap()
66    );
67    assert!(serde_json::from_str::<Language>(r#""2Xs""#).is_err());
68
69    assert_eq!(
70        serde_json::to_string(&"Latn".parse::<Script>().unwrap()).unwrap(),
71        r#""Latn""#
72    );
73    assert_eq!(
74        serde_json::from_str::<Script>(r#""Latn""#).unwrap(),
75        "Latn".parse::<Script>().unwrap()
76    );
77    assert!(serde_json::from_str::<Script>(r#""2Xs""#).is_err());
78
79    assert_eq!(
80        serde_json::to_string(&"US".parse::<Region>().unwrap()).unwrap(),
81        r#""US""#
82    );
83    assert_eq!(
84        serde_json::from_str::<Region>(r#""US""#).unwrap(),
85        "US".parse::<Region>().unwrap()
86    );
87    assert!(serde_json::from_str::<Region>(r#""2Xs""#).is_err());
88}
89
90#[test]
91fn postcard() {
92    use crate::langid;
93    use crate::subtags::{Language, Region, Script};
94
95    assert_eq!(
96        postcard::to_stdvec(&langid!("en-US")).unwrap(),
97        &[5, b'e', b'n', b'-', b'U', b'S']
98    );
99    assert_eq!(
100        postcard::from_bytes::<LanguageIdentifier>(&[5, b'e', b'n', b'-', b'U', b'S']).unwrap(),
101        langid!("en-US")
102    );
103    assert!(postcard::from_bytes::<LanguageIdentifier>(&[3, b'2', b'X', b's']).is_err());
104
105    assert_eq!(
106        postcard::to_stdvec(&"fr".parse::<Language>().unwrap()).unwrap(),
107        b"fr\0"
108    );
109    assert_eq!(
110        postcard::from_bytes::<Language>(b"fr\0").unwrap(),
111        "fr".parse::<Language>().unwrap()
112    );
113    assert!(postcard::from_bytes::<Language>(b"2Xs").is_err());
114
115    assert_eq!(
116        postcard::to_stdvec(&"Latn".parse::<Script>().unwrap()).unwrap(),
117        b"Latn"
118    );
119    assert_eq!(
120        postcard::from_bytes::<Script>(b"Latn").unwrap(),
121        "Latn".parse::<Script>().unwrap()
122    );
123    assert!(postcard::from_bytes::<Script>(b"2Xss").is_err());
124
125    assert_eq!(
126        postcard::to_stdvec(&"US".parse::<Region>().unwrap()).unwrap(),
127        b"US\0"
128    );
129    assert_eq!(
130        postcard::from_bytes::<Region>(b"US\0").unwrap(),
131        "US".parse::<Region>().unwrap()
132    );
133    assert!(postcard::from_bytes::<Region>(b"2Xs").is_err());
134}