//! Deserialization support for [`Datetime`][crate::Datetime] use alloc::string::ToString; use serde_core::de::value::BorrowedStrDeserializer; use serde_core::de::IntoDeserializer; /// Check if deserializing a [`Datetime`][crate::Datetime] pub fn is_datetime(name: &'static str) -> bool { crate::datetime::is_datetime(name) } /// Deserializer / format support for emitting [`Datetime`][crate::Datetime] pub struct DatetimeDeserializer { date: Option, _error: core::marker::PhantomData, } impl DatetimeDeserializer { /// Create a deserializer to emit [`Datetime`][crate::Datetime] pub fn new(date: crate::Datetime) -> Self { Self { date: Some(date), _error: Default::default(), } } } impl<'de, E> serde_core::de::MapAccess<'de> for DatetimeDeserializer where E: serde_core::de::Error, { type Error = E; fn next_key_seed(&mut self, seed: K) -> Result, Self::Error> where K: serde_core::de::DeserializeSeed<'de>, { if self.date.is_some() { seed.deserialize(BorrowedStrDeserializer::new(crate::datetime::FIELD)) .map(Some) } else { Ok(None) } } fn next_value_seed(&mut self, seed: V) -> Result where V: serde_core::de::DeserializeSeed<'de>, { if let Some(date) = self.date.take() { seed.deserialize(date.to_string().into_deserializer()) } else { panic!("next_value_seed called before next_key_seed") } } } /// Integrate [`Datetime`][crate::Datetime] into an untagged deserialize #[cfg(feature = "alloc")] pub enum VisitMap<'de> { /// The map was deserialized as a [Datetime][crate::Datetime] value Datetime(crate::Datetime), /// The map is of an unknown format and needs further deserialization Key(alloc::borrow::Cow<'de, str>), } impl<'de> VisitMap<'de> { /// Determine the type of the map by deserializing it pub fn next_key_seed>( visitor: &mut V, ) -> Result, V::Error> { let mut key = None; let Some(()) = visitor.next_key_seed(DatetimeOrTable::new(&mut key))? else { return Ok(None); }; let result = if let Some(key) = key { VisitMap::Key(key) } else { let date: crate::datetime::DatetimeFromString = visitor.next_value()?; VisitMap::Datetime(date.value) }; Ok(Some(result)) } } struct DatetimeOrTable<'m, 'de> { key: &'m mut Option>, } impl<'m, 'de> DatetimeOrTable<'m, 'de> { fn new(key: &'m mut Option>) -> Self { *key = None; Self { key } } } impl<'de> serde_core::de::DeserializeSeed<'de> for DatetimeOrTable<'_, 'de> { type Value = (); fn deserialize(self, deserializer: D) -> Result where D: serde_core::de::Deserializer<'de>, { deserializer.deserialize_any(self) } } impl<'de> serde_core::de::Visitor<'de> for DatetimeOrTable<'_, 'de> { type Value = (); fn expecting(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { formatter.write_str("a string key") } fn visit_str(self, s: &str) -> Result where E: serde_core::de::Error, { if s == crate::datetime::FIELD { *self.key = None; Ok(()) } else { use crate::alloc::borrow::ToOwned as _; *self.key = Some(alloc::borrow::Cow::Owned(s.to_owned())); Ok(()) } } fn visit_borrowed_str(self, s: &'de str) -> Result where E: serde_core::de::Error, { if s == crate::datetime::FIELD { *self.key = None; Ok(()) } else { *self.key = Some(alloc::borrow::Cow::Borrowed(s)); Ok(()) } } #[allow(unused_qualifications)] fn visit_string(self, s: alloc::string::String) -> Result where E: serde_core::de::Error, { if s == crate::datetime::FIELD { *self.key = None; Ok(()) } else { *self.key = Some(alloc::borrow::Cow::Owned(s)); Ok(()) } } }