icu_locale_core/preferences/extensions/unicode/macros/
struct_keyword.rs1#[macro_export]
29#[doc(hidden)]
30macro_rules! __struct_keyword {
31 ($(#[$doc:meta])* $([$derive_attrs:ty])? $name:ident, $ext_key:literal, $value:ty, $try_from:expr, $into:expr) => {
32 $(#[$doc])*
33 #[derive(Debug, Clone, Eq, PartialEq, Hash)]
34 $(#[derive($derive_attrs)])?
35 #[allow(clippy::exhaustive_structs)] pub struct $name($value);
37
38 impl TryFrom<$crate::extensions::unicode::Value> for $name {
39 type Error = $crate::preferences::extensions::unicode::errors::PreferencesParseError;
40
41 fn try_from(
42 input: $crate::extensions::unicode::Value,
43 ) -> Result<Self, Self::Error> {
44 $try_from(input)
45 }
46 }
47
48 impl From<$name> for $crate::extensions::unicode::Value {
49 fn from(input: $name) -> $crate::extensions::unicode::Value {
50 $into(input)
51 }
52 }
53
54 impl $crate::preferences::PreferenceKey for $name {
55 fn unicode_extension_key() -> Option<$crate::extensions::unicode::Key> {
56 Some($crate::extensions::unicode::key!($ext_key))
57 }
58
59 fn try_from_key_value(
60 key: &$crate::extensions::unicode::Key,
61 value: &$crate::extensions::unicode::Value,
62 ) -> Result<Option<Self>, $crate::preferences::extensions::unicode::errors::PreferencesParseError> {
63 if Self::unicode_extension_key() == Some(*key) {
64 let result = Self::try_from(value.clone())?;
65 Ok(Some(result))
66 } else {
67 Ok(None)
68 }
69 }
70
71 fn unicode_extension_value(
72 &self,
73 ) -> Option<$crate::extensions::unicode::Value> {
74 Some(self.clone().into())
75 }
76 }
77
78 impl core::ops::Deref for $name {
79 type Target = $value;
80
81 fn deref(&self) -> &Self::Target {
82 &self.0
83 }
84 }
85 };
86}
87pub use __struct_keyword as struct_keyword;
88
89#[cfg(test)]
90mod tests {
91 use super::*;
92 use crate::{
93 extensions::unicode,
94 subtags::{subtag, Subtag},
95 };
96 use core::str::FromStr;
97
98 #[test]
99 fn struct_keywords_test() {
100 struct_keyword!(
101 DummyKeyword,
102 "dk",
103 Subtag,
104 |input: unicode::Value| {
105 if let Some(subtag) = input.into_single_subtag() {
106 if subtag.len() == 3 {
107 return Ok(DummyKeyword(subtag));
108 }
109 }
110 Err(crate::preferences::extensions::unicode::errors::PreferencesParseError::InvalidKeywordValue)
111 },
112 |input: DummyKeyword| { unicode::Value::from_subtag(Some(input.0)) }
113 );
114
115 let v = unicode::Value::from_str("foo").unwrap();
116 let dk: DummyKeyword = v.clone().try_into().unwrap();
117 assert_eq!(dk, DummyKeyword(subtag!("foo")));
118 assert_eq!(unicode::Value::from(dk), v);
119
120 let v = unicode::Value::from_str("foobar").unwrap();
121 let dk: Result<DummyKeyword, _> = v.clone().try_into();
122 assert!(dk.is_err());
123 }
124}