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