icu_datetime/provider/pattern/common/
serde.rs1use super::super::{PatternItem, TimeGranularity};
6use ::serde::{de, Deserialize, Deserializer};
7use alloc::{fmt, format, vec::Vec};
8
9#[cfg(feature = "datagen")]
10use ::serde::{ser, Serialize};
11
12mod reference {
13 use super::super::super::reference::Pattern;
14 use super::*;
15
16 #[derive(Debug, Clone, PartialEq, Deserialize)]
19 #[cfg_attr(feature = "datagen", derive(Serialize))]
20 struct PatternForSerde {
21 items: Vec<PatternItem>,
22 time_granularity: TimeGranularity,
23 }
24
25 impl From<PatternForSerde> for Pattern {
26 fn from(pfs: PatternForSerde) -> Self {
27 Self {
28 items: pfs.items,
29 time_granularity: pfs.time_granularity,
30 }
31 }
32 }
33
34 impl From<&Pattern> for PatternForSerde {
35 fn from(pfs: &Pattern) -> Self {
36 Self {
37 items: pfs.items.clone(),
38 time_granularity: pfs.time_granularity,
39 }
40 }
41 }
42
43 #[allow(clippy::upper_case_acronyms)]
44 pub(crate) struct DeserializePatternUTS35String;
45
46 impl de::Visitor<'_> for DeserializePatternUTS35String {
47 type Value = Pattern;
48
49 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
50 write!(formatter, "a valid pattern.")
51 }
52
53 fn visit_str<E>(self, pattern_string: &str) -> Result<Self::Value, E>
54 where
55 E: de::Error,
56 {
57 pattern_string.parse().map_err(|err| {
59 de::Error::invalid_value(
60 de::Unexpected::Other(&format!("{err}")),
61 &"a valid UTS 35 pattern string",
62 )
63 })
64 }
65 }
66
67 impl<'de> Deserialize<'de> for Pattern {
68 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
69 where
70 D: Deserializer<'de>,
71 {
72 if deserializer.is_human_readable() {
73 deserializer.deserialize_str(DeserializePatternUTS35String)
74 } else {
75 let pattern = PatternForSerde::deserialize(deserializer)?;
76 Ok(Pattern::from(pattern))
77 }
78 }
79 }
80
81 #[cfg(feature = "datagen")]
82 impl Serialize for Pattern {
83 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
84 where
85 S: ser::Serializer,
86 {
87 if serializer.is_human_readable() {
88 serializer.serialize_str(&self.to_runtime_pattern().to_string())
89 } else {
90 let pfs = PatternForSerde::from(self);
91 pfs.serialize(serializer)
92 }
93 }
94 }
95
96 #[cfg(all(test, feature = "datagen"))]
97 mod test {
98 use super::*;
99
100 #[test]
101 fn reference_pattern_serde_human_readable_test() {
102 let pattern: Pattern = "y-M-d HH:mm".parse().expect("Failed to parse pattern");
103 let json = serde_json::to_string(&pattern).expect("Failed to serialize pattern");
104 let result: Pattern =
105 serde_json::from_str(&json).expect("Failed to deserialize pattern");
106 assert_eq!(pattern, result);
107 }
108
109 #[test]
110 fn reference_pattern_serde_bincode_test() {
111 let pattern: Pattern = "y-M-d HH:mm".parse().expect("Failed to parse pattern");
112 let bytes = bincode::serialize(&pattern).expect("Failed to serialize pattern");
113 let result: Pattern =
114 bincode::deserialize(&bytes).expect("Failed to deserialize pattern");
115 assert_eq!(pattern, result);
116 }
117 }
118}
119
120mod runtime {
121 use super::super::super::{runtime::Pattern, runtime::PatternMetadata, PatternItem};
122 use super::*;
123 use zerovec::ZeroVec;
124
125 #[derive(Debug, Clone, PartialEq, Deserialize)]
128 #[cfg_attr(feature = "datagen", derive(Serialize))]
129 struct PatternForSerde<'data> {
130 #[serde(borrow)]
131 pub items: ZeroVec<'data, PatternItem>,
132 pub time_granularity: TimeGranularity,
133 }
134
135 impl<'data> From<PatternForSerde<'data>> for Pattern<'data> {
136 fn from(pfs: PatternForSerde<'data>) -> Self {
137 Self {
138 items: pfs.items,
139 metadata: PatternMetadata::from_time_granularity(pfs.time_granularity),
140 }
141 }
142 }
143
144 #[allow(clippy::upper_case_acronyms)]
145 struct DeserializePatternUTS35String;
146
147 impl<'de> de::Visitor<'de> for DeserializePatternUTS35String {
148 type Value = Pattern<'de>;
149
150 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
151 write!(formatter, "a valid pattern.")
152 }
153
154 fn visit_str<E>(self, pattern_string: &str) -> Result<Self::Value, E>
155 where
156 E: de::Error,
157 {
158 let reference_deserializer = super::reference::DeserializePatternUTS35String;
160 let pattern = reference_deserializer.visit_str(pattern_string)?;
161
162 Ok(Self::Value::from(&pattern))
163 }
164 }
165
166 impl<'de: 'data, 'data> Deserialize<'de> for Pattern<'data> {
167 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
168 where
169 D: Deserializer<'de>,
170 {
171 if deserializer.is_human_readable() {
172 deserializer.deserialize_str(DeserializePatternUTS35String)
173 } else {
174 let pattern = PatternForSerde::deserialize(deserializer)?;
175 Ok(Pattern::from(pattern))
176 }
177 }
178 }
179
180 #[cfg(feature = "datagen")]
181 impl Serialize for Pattern<'_> {
182 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
183 where
184 S: ser::Serializer,
185 {
186 if serializer.is_human_readable() {
187 serializer.serialize_str(&self.to_string())
188 } else {
189 let pfs = PatternForSerde {
190 items: self.items.clone(),
191 time_granularity: self.metadata.time_granularity(),
192 };
193 pfs.serialize(serializer)
194 }
195 }
196 }
197
198 #[cfg(all(test, feature = "datagen"))]
199 mod test {
200 use super::*;
201
202 #[test]
203 fn runtime_pattern_serde_human_readable_test() {
204 let pattern: Pattern = "y-M-d HH:mm".parse().expect("Failed to parse pattern");
205 let json = serde_json::to_string(&pattern).expect("Failed to serialize pattern");
206 let result: Pattern =
207 serde_json::from_str(&json).expect("Failed to deserialize pattern");
208 assert_eq!(pattern, result);
209 }
210
211 #[test]
212 fn runtime_pattern_serde_bincode_test() {
213 let pattern: Pattern = "y-M-d HH:mm".parse().expect("Failed to parse pattern");
214 let bytes = bincode::serialize(&pattern).expect("Failed to serialize pattern");
215 let result: Pattern =
216 bincode::deserialize(&bytes).expect("Failed to deserialize pattern");
217 assert_eq!(pattern, result);
218 }
219 }
220
221 mod generic {
222 use super::super::super::super::runtime::GenericPattern;
223 use super::*;
224
225 #[allow(clippy::upper_case_acronyms)]
226 struct DeserializeGenericPatternUTS35String;
227
228 impl<'de> de::Visitor<'de> for DeserializeGenericPatternUTS35String {
229 type Value = GenericPattern<'de>;
230
231 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
232 write!(formatter, "a valid pattern.")
233 }
234
235 fn visit_str<E>(self, pattern_string: &str) -> Result<Self::Value, E>
236 where
237 E: de::Error,
238 {
239 let pattern = pattern_string
241 .parse()
242 .map_err(|_| E::custom("Failed to parse pattern"))?;
243 Ok(GenericPattern::from(&pattern))
244 }
245 }
246
247 impl<'de: 'data, 'data> Deserialize<'de> for GenericPattern<'data> {
248 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
249 where
250 D: Deserializer<'de>,
251 {
252 if deserializer.is_human_readable() {
253 deserializer.deserialize_str(DeserializeGenericPatternUTS35String)
254 } else {
255 let items = ZeroVec::deserialize(deserializer)?;
256 Ok(Self { items })
257 }
258 }
259 }
260
261 #[cfg(feature = "datagen")]
262 impl Serialize for GenericPattern<'_> {
263 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
264 where
265 S: ser::Serializer,
266 {
267 if serializer.is_human_readable() {
268 let string = self.to_string();
270 serializer.serialize_str(&string)
271 } else {
272 self.items.serialize(serializer)
273 }
274 }
275 }
276
277 #[cfg(all(test, feature = "datagen"))]
278 mod test {
279 use super::*;
280
281 #[test]
282 fn runtime_generic_pattern_serde_human_readable_test() {
283 let pattern: GenericPattern =
284 "{0} 'and' {1}".parse().expect("Failed to parse pattern");
285 let json = serde_json::to_string(&pattern).expect("Failed to serialize pattern");
286 let result: GenericPattern =
287 serde_json::from_str(&json).expect("Failed to deserialize pattern");
288 assert_eq!(pattern, result);
289 }
290
291 #[test]
292 fn runtime_generic_pattern_serde_bincode_test() {
293 let pattern: GenericPattern =
294 "{0} 'and' {1}".parse().expect("Failed to parse pattern");
295 let bytes = bincode::serialize(&pattern).expect("Failed to serialize pattern");
296 let result: GenericPattern =
297 bincode::deserialize(&bytes).expect("Failed to deserialize pattern");
298 assert_eq!(pattern, result);
299 }
300 }
301 }
302}