Add optional support for chrono::DateTime

This commit is contained in:
Dirkjan Ochtman 2022-11-21 21:20:38 -08:00
parent 104012d3bc
commit ae2128a77e
3 changed files with 50 additions and 0 deletions

View File

@ -6,6 +6,7 @@ workspace = ".."
license = "Apache-2.0 OR MIT"
[dependencies]
chrono = { version = "0.4.23", optional = true }
macros = { package = "instant-xml-macros", version = "0.1", path = "../instant-xml-macros" }
thiserror = "1.0.29"
xmlparser = "0.13.3"

View File

@ -2,6 +2,9 @@ use std::borrow::Cow;
use std::fmt;
use std::str::FromStr;
#[cfg(feature = "chrono")]
use chrono::{DateTime, Utc};
use crate::{de::Node, Deserializer, Error, FromXml, Kind, Serializer, ToXml};
// Deserializer
@ -393,3 +396,28 @@ where
const KIND: Kind = Kind::Vec;
}
#[cfg(feature = "chrono")]
impl ToXml for DateTime<Utc> {
fn serialize<W: fmt::Write + ?Sized>(
&self,
serializer: &mut Serializer<W>,
) -> Result<(), Error> {
serializer.write_str(&self.to_rfc3339())
}
const KIND: Kind = Kind::Scalar;
}
#[cfg(feature = "chrono")]
impl<'xml> FromXml<'xml> for DateTime<Utc> {
fn deserialize<'cx>(deserializer: &'cx mut Deserializer<'cx, 'xml>) -> Result<Self, Error> {
let data = deserializer.take_str()?;
match DateTime::parse_from_rfc3339(data) {
Ok(dt) if dt.timezone().utc_minus_local() == 0 => Ok(dt.with_timezone(&Utc)),
_ => Err(Error::Other("invalid date/time".into())),
}
}
const KIND: Kind = Kind::Scalar;
}

View File

@ -0,0 +1,21 @@
#![cfg(feature = "chrono")]
use chrono::{DateTime, TimeZone, Utc};
use instant_xml::{from_str, to_string, FromXml, ToXml};
#[derive(Debug, Eq, PartialEq, FromXml, ToXml)]
struct Test {
dt: DateTime<Utc>,
}
#[test]
fn datetime() {
let dt = Utc.with_ymd_and_hms(2022, 11, 21, 21, 17, 23).unwrap();
let test = Test { dt };
let xml = "<Test><dt>2022-11-21T21:17:23+00:00</dt></Test>";
assert_eq!(to_string(&test).unwrap(), xml);
assert_eq!(from_str::<Test>(xml).unwrap(), test);
let zulu = xml.replace("+00:00", "Z");
assert_eq!(from_str::<Test>(&zulu).unwrap(), test);
}