1use core::fmt;
4use core::marker::PhantomData;
5
6#[cfg(feature = "parsing")]
7use serde_core::Deserializer;
8use serde_core::de;
9
10#[cfg(feature = "parsing")]
11use super::{
12 DATE_FORMAT, OFFSET_DATE_TIME_FORMAT, PRIMITIVE_DATE_TIME_FORMAT, TIME_FORMAT,
13 UTC_DATE_TIME_FORMAT, UTC_OFFSET_FORMAT,
14};
15use crate::error::ComponentRange;
16#[cfg(feature = "parsing")]
17use crate::format_description::well_known::*;
18use crate::{
19 Date, Duration, Month, OffsetDateTime, PrimitiveDateTime, Time, UtcDateTime, UtcOffset, Weekday,
20};
21
22pub(super) struct Visitor<T>(pub(super) PhantomData<T>)
24where
25 T: ?Sized;
26
27impl<'a> de::Visitor<'a> for Visitor<Date> {
28 type Value = Date;
29
30 #[inline]
31 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
32 formatter.write_str("a `Date`")
33 }
34
35 #[cfg(feature = "parsing")]
36 #[inline]
37 fn visit_str<E>(self, value: &str) -> Result<Date, E>
38 where
39 E: de::Error,
40 {
41 Date::parse(value, &DATE_FORMAT).map_err(E::custom)
42 }
43
44 #[inline]
45 fn visit_seq<A>(self, mut seq: A) -> Result<Date, A::Error>
46 where
47 A: de::SeqAccess<'a>,
48 {
49 let year = item!(seq, "year")?;
50 let ordinal = item!(seq, "day of year")?;
51 Date::from_ordinal_date(year, ordinal).map_err(ComponentRange::into_de_error)
52 }
53}
54
55impl<'a> de::Visitor<'a> for Visitor<Duration> {
56 type Value = Duration;
57
58 #[inline]
59 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
60 formatter.write_str("a `Duration`")
61 }
62
63 #[inline]
64 fn visit_str<E>(self, value: &str) -> Result<Duration, E>
65 where
66 E: de::Error,
67 {
68 let (seconds, nanoseconds) = value.split_once('.').ok_or_else(|| {
69 de::Error::invalid_value(de::Unexpected::Str(value), &"a decimal point")
70 })?;
71
72 let seconds = seconds
73 .parse()
74 .map_err(|_| de::Error::invalid_value(de::Unexpected::Str(seconds), &"seconds"))?;
75 let mut nanoseconds = nanoseconds.parse().map_err(|_| {
76 de::Error::invalid_value(de::Unexpected::Str(nanoseconds), &"nanoseconds")
77 })?;
78
79 if seconds < 0
80 || (seconds == 0 && value.starts_with("-"))
82 {
83 nanoseconds *= -1;
84 }
85
86 Ok(Duration::new(seconds, nanoseconds))
87 }
88
89 #[inline]
90 fn visit_seq<A>(self, mut seq: A) -> Result<Duration, A::Error>
91 where
92 A: de::SeqAccess<'a>,
93 {
94 let seconds = item!(seq, "seconds")?;
95 let nanoseconds = item!(seq, "nanoseconds")?;
96 Ok(Duration::new(seconds, nanoseconds))
97 }
98}
99
100impl<'a> de::Visitor<'a> for Visitor<OffsetDateTime> {
101 type Value = OffsetDateTime;
102
103 #[inline]
104 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
105 formatter.write_str("an `OffsetDateTime`")
106 }
107
108 #[cfg(feature = "parsing")]
109 #[inline]
110 fn visit_str<E>(self, value: &str) -> Result<OffsetDateTime, E>
111 where
112 E: de::Error,
113 {
114 OffsetDateTime::parse(value, &OFFSET_DATE_TIME_FORMAT).map_err(E::custom)
115 }
116
117 #[inline]
118 fn visit_seq<A>(self, mut seq: A) -> Result<OffsetDateTime, A::Error>
119 where
120 A: de::SeqAccess<'a>,
121 {
122 let year = item!(seq, "year")?;
123 let ordinal = item!(seq, "day of year")?;
124 let hour = item!(seq, "hour")?;
125 let minute = item!(seq, "minute")?;
126 let second = item!(seq, "second")?;
127 let nanosecond = item!(seq, "nanosecond")?;
128 let offset_hours = item!(seq, "offset hours")?;
129 let offset_minutes = item!(seq, "offset minutes")?;
130 let offset_seconds = item!(seq, "offset seconds")?;
131
132 Date::from_ordinal_date(year, ordinal)
133 .and_then(|date| date.with_hms_nano(hour, minute, second, nanosecond))
134 .and_then(|datetime| {
135 UtcOffset::from_hms(offset_hours, offset_minutes, offset_seconds)
136 .map(|offset| datetime.assume_offset(offset))
137 })
138 .map_err(ComponentRange::into_de_error)
139 }
140}
141
142impl<'a> de::Visitor<'a> for Visitor<PrimitiveDateTime> {
143 type Value = PrimitiveDateTime;
144
145 #[inline]
146 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
147 formatter.write_str("a `PrimitiveDateTime`")
148 }
149
150 #[cfg(feature = "parsing")]
151 #[inline]
152 fn visit_str<E>(self, value: &str) -> Result<PrimitiveDateTime, E>
153 where
154 E: de::Error,
155 {
156 PrimitiveDateTime::parse(value, &PRIMITIVE_DATE_TIME_FORMAT).map_err(E::custom)
157 }
158
159 #[inline]
160 fn visit_seq<A>(self, mut seq: A) -> Result<PrimitiveDateTime, A::Error>
161 where
162 A: de::SeqAccess<'a>,
163 {
164 let year = item!(seq, "year")?;
165 let ordinal = item!(seq, "day of year")?;
166 let hour = item!(seq, "hour")?;
167 let minute = item!(seq, "minute")?;
168 let second = item!(seq, "second")?;
169 let nanosecond = item!(seq, "nanosecond")?;
170
171 Date::from_ordinal_date(year, ordinal)
172 .and_then(|date| date.with_hms_nano(hour, minute, second, nanosecond))
173 .map_err(ComponentRange::into_de_error)
174 }
175}
176
177impl<'a> de::Visitor<'a> for Visitor<UtcDateTime> {
178 type Value = UtcDateTime;
179
180 #[inline]
181 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
182 formatter.write_str("a `PrimitiveDateTime`")
183 }
184
185 #[cfg(feature = "parsing")]
186 #[inline]
187 fn visit_str<E>(self, value: &str) -> Result<UtcDateTime, E>
188 where
189 E: de::Error,
190 {
191 UtcDateTime::parse(value, &UTC_DATE_TIME_FORMAT).map_err(E::custom)
192 }
193
194 #[inline]
195 fn visit_seq<A>(self, mut seq: A) -> Result<UtcDateTime, A::Error>
196 where
197 A: de::SeqAccess<'a>,
198 {
199 let year = item!(seq, "year")?;
200 let ordinal = item!(seq, "day of year")?;
201 let hour = item!(seq, "hour")?;
202 let minute = item!(seq, "minute")?;
203 let second = item!(seq, "second")?;
204 let nanosecond = item!(seq, "nanosecond")?;
205
206 Date::from_ordinal_date(year, ordinal)
207 .and_then(|date| date.with_hms_nano(hour, minute, second, nanosecond))
208 .map(UtcDateTime::from_primitive)
209 .map_err(ComponentRange::into_de_error)
210 }
211}
212
213impl<'a> de::Visitor<'a> for Visitor<Time> {
214 type Value = Time;
215
216 #[inline]
217 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
218 formatter.write_str("a `Time`")
219 }
220
221 #[cfg(feature = "parsing")]
222 #[inline]
223 fn visit_str<E>(self, value: &str) -> Result<Time, E>
224 where
225 E: de::Error,
226 {
227 Time::parse(value, &TIME_FORMAT).map_err(E::custom)
228 }
229
230 #[inline]
231 fn visit_seq<A>(self, mut seq: A) -> Result<Time, A::Error>
232 where
233 A: de::SeqAccess<'a>,
234 {
235 let hour = item!(seq, "hour")?;
236 let minute = item!(seq, "minute")?;
237 let second = item!(seq, "second")?;
238 let nanosecond = item!(seq, "nanosecond")?;
239
240 Time::from_hms_nano(hour, minute, second, nanosecond).map_err(ComponentRange::into_de_error)
241 }
242}
243
244impl<'a> de::Visitor<'a> for Visitor<UtcOffset> {
245 type Value = UtcOffset;
246
247 #[inline]
248 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
249 formatter.write_str("a `UtcOffset`")
250 }
251
252 #[cfg(feature = "parsing")]
253 #[inline]
254 fn visit_str<E>(self, value: &str) -> Result<UtcOffset, E>
255 where
256 E: de::Error,
257 {
258 UtcOffset::parse(value, &UTC_OFFSET_FORMAT).map_err(E::custom)
259 }
260
261 #[inline]
262 fn visit_seq<A>(self, mut seq: A) -> Result<UtcOffset, A::Error>
263 where
264 A: de::SeqAccess<'a>,
265 {
266 let hours = item!(seq, "offset hours")?;
267 let mut minutes = 0;
268 let mut seconds = 0;
269
270 if let Ok(Some(min)) = seq.next_element() {
271 minutes = min;
272 if let Ok(Some(sec)) = seq.next_element() {
273 seconds = sec;
274 }
275 };
276
277 UtcOffset::from_hms(hours, minutes, seconds).map_err(ComponentRange::into_de_error)
278 }
279}
280
281impl de::Visitor<'_> for Visitor<Weekday> {
282 type Value = Weekday;
283
284 #[inline]
285 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
286 formatter.write_str("a `Weekday`")
287 }
288
289 #[inline]
290 fn visit_str<E>(self, value: &str) -> Result<Weekday, E>
291 where
292 E: de::Error,
293 {
294 match value {
295 "Monday" => Ok(Weekday::Monday),
296 "Tuesday" => Ok(Weekday::Tuesday),
297 "Wednesday" => Ok(Weekday::Wednesday),
298 "Thursday" => Ok(Weekday::Thursday),
299 "Friday" => Ok(Weekday::Friday),
300 "Saturday" => Ok(Weekday::Saturday),
301 "Sunday" => Ok(Weekday::Sunday),
302 _ => Err(E::invalid_value(de::Unexpected::Str(value), &"a `Weekday`")),
303 }
304 }
305
306 #[inline]
307 fn visit_u64<E>(self, value: u64) -> Result<Weekday, E>
308 where
309 E: de::Error,
310 {
311 match value {
312 1 => Ok(Weekday::Monday),
313 2 => Ok(Weekday::Tuesday),
314 3 => Ok(Weekday::Wednesday),
315 4 => Ok(Weekday::Thursday),
316 5 => Ok(Weekday::Friday),
317 6 => Ok(Weekday::Saturday),
318 7 => Ok(Weekday::Sunday),
319 _ => Err(E::invalid_value(
320 de::Unexpected::Unsigned(value),
321 &"a value in the range 1..=7",
322 )),
323 }
324 }
325}
326
327impl de::Visitor<'_> for Visitor<Month> {
328 type Value = Month;
329
330 #[inline]
331 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
332 formatter.write_str("a `Month`")
333 }
334
335 #[inline]
336 fn visit_str<E>(self, value: &str) -> Result<Month, E>
337 where
338 E: de::Error,
339 {
340 match value {
341 "January" => Ok(Month::January),
342 "February" => Ok(Month::February),
343 "March" => Ok(Month::March),
344 "April" => Ok(Month::April),
345 "May" => Ok(Month::May),
346 "June" => Ok(Month::June),
347 "July" => Ok(Month::July),
348 "August" => Ok(Month::August),
349 "September" => Ok(Month::September),
350 "October" => Ok(Month::October),
351 "November" => Ok(Month::November),
352 "December" => Ok(Month::December),
353 _ => Err(E::invalid_value(de::Unexpected::Str(value), &"a `Month`")),
354 }
355 }
356
357 #[inline]
358 fn visit_u64<E>(self, value: u64) -> Result<Month, E>
359 where
360 E: de::Error,
361 {
362 match value {
363 1 => Ok(Month::January),
364 2 => Ok(Month::February),
365 3 => Ok(Month::March),
366 4 => Ok(Month::April),
367 5 => Ok(Month::May),
368 6 => Ok(Month::June),
369 7 => Ok(Month::July),
370 8 => Ok(Month::August),
371 9 => Ok(Month::September),
372 10 => Ok(Month::October),
373 11 => Ok(Month::November),
374 12 => Ok(Month::December),
375 _ => Err(E::invalid_value(
376 de::Unexpected::Unsigned(value),
377 &"a value in the range 1..=12",
378 )),
379 }
380 }
381}
382
383macro_rules! well_known {
385 ($article:literal, $name:literal, $($ty:tt)+) => {
386 #[cfg(feature = "parsing")]
387 impl de::Visitor<'_> for Visitor<$($ty)+> {
388 type Value = OffsetDateTime;
389
390 #[inline]
391 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
392 formatter.write_str(concat!($article, " ", $name, "-formatted `OffsetDateTime`"))
393 }
394
395 #[inline]
396 fn visit_str<E>(self, value: &str) -> Result<OffsetDateTime, E>
397 where
398 E: de::Error,
399 {
400 OffsetDateTime::parse(value, &$($ty)+).map_err(E::custom)
401 }
402 }
403
404 #[cfg(feature = "parsing")]
405 impl<'a> de::Visitor<'a> for Visitor<Option<$($ty)+>> {
406 type Value = Option<OffsetDateTime>;
407
408 #[inline]
409 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
410 formatter.write_str(concat!(
411 $article,
412 " ",
413 $name,
414 "-formatted `Option<OffsetDateTime>`"
415 ))
416 }
417
418 #[inline]
419 fn visit_some<D>(self, deserializer: D) -> Result<Option<OffsetDateTime>, D::Error>
420 where
421 D: Deserializer<'a>,
422 {
423 deserializer
424 .deserialize_any(Visitor::<$($ty)+>(PhantomData))
425 .map(Some)
426 }
427
428 #[inline]
429 fn visit_none<E>(self) -> Result<Option<OffsetDateTime>, E>
430 where
431 E: de::Error,
432 {
433 Ok(None)
434 }
435
436 #[inline]
437 fn visit_unit<E>(self) -> Result<Self::Value, E>
438 where
439 E: de::Error,
440 {
441 Ok(None)
442 }
443 }
444 };
445}
446
447well_known!("an", "RFC2822", Rfc2822);
448well_known!("an", "RFC3339", Rfc3339);
449well_known!(
450 "an",
451 "ISO 8601",
452 Iso8601::<{ super::iso8601::SERDE_CONFIG }>
453);