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