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