// This file is part of ICU4X. For terms of use, please see the file // called LICENSE at the top level of the ICU4X source tree // (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ). use crate::{LanguageIdentifier, Locale}; use core::{fmt::Display, marker::PhantomData, str::FromStr}; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use writeable::Writeable; impl Serialize for LanguageIdentifier { fn serialize(&self, serializer: S) -> Result where S: Serializer, { serializer.serialize_str(&self.write_to_string()) } } impl Serialize for Locale { fn serialize(&self, serializer: S) -> Result where S: Serializer, { serializer.serialize_str(&self.write_to_string()) } } struct ParseVisitor(PhantomData); impl serde::de::Visitor<'_> for ParseVisitor where T: FromStr, ::Err: Display, { type Value = T; fn expecting(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { write!(formatter, "a valid Unicode Language or Locale Identifier") } fn visit_str(self, s: &str) -> Result where E: serde::de::Error, { s.parse::().map_err(serde::de::Error::custom) } } impl<'de> Deserialize<'de> for LanguageIdentifier { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, { deserializer.deserialize_str(ParseVisitor(PhantomData)) } } impl<'de> Deserialize<'de> for Locale { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, { deserializer.deserialize_str(ParseVisitor(PhantomData)) } } #[test] fn json() { use crate::subtags::{Language, Region, Script}; use crate::{langid, locale}; assert_eq!( serde_json::to_string(&langid!("en-US")).unwrap(), r#""en-US""# ); assert_eq!( serde_json::from_str::(r#""en-US""#).unwrap(), langid!("en-US") ); assert_eq!( serde_json::from_reader::<_, LanguageIdentifier>(&br#""en-US""#[..]).unwrap(), langid!("en-US") ); assert!(serde_json::from_str::(r#""2Xs""#).is_err()); assert_eq!( serde_json::to_string(&locale!("en-US-u-hc-h12")).unwrap(), r#""en-US-u-hc-h12""# ); assert_eq!( serde_json::from_str::(r#""en-US-u-hc-h12""#).unwrap(), locale!("en-US-u-hc-h12") ); assert_eq!( serde_json::from_reader::<_, Locale>(&br#""en-US-u-hc-h12""#[..]).unwrap(), locale!("en-US-u-hc-h12") ); assert!(serde_json::from_str::(r#""2Xs""#).is_err()); assert_eq!( serde_json::to_string(&"fr".parse::().unwrap()).unwrap(), r#""fr""# ); assert_eq!( serde_json::from_str::(r#""fr""#).unwrap(), "fr".parse::().unwrap() ); assert_eq!( serde_json::from_reader::<_, Language>(&br#""fr""#[..]).unwrap(), "fr".parse::().unwrap() ); assert!(serde_json::from_str::(r#""2Xs""#).is_err()); assert_eq!( serde_json::to_string(&"Latn".parse::