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