//! Serde visitor for various types. use core::fmt; use core::marker::PhantomData; use serde::de; #[cfg(feature = "parsing")] use serde::Deserializer; #[cfg(feature = "parsing")] use super::{ DATE_FORMAT, OFFSET_DATE_TIME_FORMAT, PRIMITIVE_DATE_TIME_FORMAT, TIME_FORMAT, UTC_OFFSET_FORMAT, }; use crate::error::ComponentRange; #[cfg(feature = "parsing")] use crate::format_description::well_known::*; use crate::{Date, Duration, Month, OffsetDateTime, PrimitiveDateTime, Time, UtcOffset, Weekday}; /// A serde visitor for various types. pub(super) struct Visitor(pub(super) PhantomData); impl<'a> de::Visitor<'a> for Visitor { type Value = Date; fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { formatter.write_str("a `Date`") } #[cfg(feature = "parsing")] fn visit_str(self, value: &str) -> Result { Date::parse(value, &DATE_FORMAT).map_err(E::custom) } fn visit_seq>(self, mut seq: A) -> Result { let year = item!(seq, "year")?; let ordinal = item!(seq, "day of year")?; Date::from_ordinal_date(year, ordinal).map_err(ComponentRange::into_de_error) } } impl<'a> de::Visitor<'a> for Visitor { type Value = Duration; fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { formatter.write_str("a `Duration`") } fn visit_str(self, value: &str) -> Result { let (seconds, nanoseconds) = value.split_once('.').ok_or_else(|| { de::Error::invalid_value(de::Unexpected::Str(value), &"a decimal point") })?; let seconds = seconds .parse() .map_err(|_| de::Error::invalid_value(de::Unexpected::Str(seconds), &"seconds"))?; let mut nanoseconds = nanoseconds.parse().map_err(|_| { de::Error::invalid_value(de::Unexpected::Str(nanoseconds), &"nanoseconds") })?; if seconds < 0 { nanoseconds *= -1; } Ok(Duration::new(seconds, nanoseconds)) } fn visit_seq>(self, mut seq: A) -> Result { let seconds = item!(seq, "seconds")?; let nanoseconds = item!(seq, "nanoseconds")?; Ok(Duration::new(seconds, nanoseconds)) } } impl<'a> de::Visitor<'a> for Visitor { type Value = OffsetDateTime; fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { formatter.write_str("an `OffsetDateTime`") } #[cfg(feature = "parsing")] fn visit_str(self, value: &str) -> Result { OffsetDateTime::parse(value, &OFFSET_DATE_TIME_FORMAT).map_err(E::custom) } fn visit_seq>(self, mut seq: A) -> Result { let year = item!(seq, "year")?; let ordinal = item!(seq, "day of year")?; let hour = item!(seq, "hour")?; let minute = item!(seq, "minute")?; let second = item!(seq, "second")?; let nanosecond = item!(seq, "nanosecond")?; let offset_hours = item!(seq, "offset hours")?; let offset_minutes = item!(seq, "offset minutes")?; let offset_seconds = item!(seq, "offset seconds")?; Date::from_ordinal_date(year, ordinal) .and_then(|date| date.with_hms_nano(hour, minute, second, nanosecond)) .and_then(|datetime| { UtcOffset::from_hms(offset_hours, offset_minutes, offset_seconds) .map(|offset| datetime.assume_offset(offset)) }) .map_err(ComponentRange::into_de_error) } } impl<'a> de::Visitor<'a> for Visitor { type Value = PrimitiveDateTime; fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { formatter.write_str("a `PrimitiveDateTime`") } #[cfg(feature = "parsing")] fn visit_str(self, value: &str) -> Result { PrimitiveDateTime::parse(value, &PRIMITIVE_DATE_TIME_FORMAT).map_err(E::custom) } fn visit_seq>(self, mut seq: A) -> Result { let year = item!(seq, "year")?; let ordinal = item!(seq, "day of year")?; let hour = item!(seq, "hour")?; let minute = item!(seq, "minute")?; let second = item!(seq, "second")?; let nanosecond = item!(seq, "nanosecond")?; Date::from_ordinal_date(year, ordinal) .and_then(|date| date.with_hms_nano(hour, minute, second, nanosecond)) .map_err(ComponentRange::into_de_error) } } impl<'a> de::Visitor<'a> for Visitor