mirror of
https://github.com/instant-labs/instant-xml.git
synced 2025-02-13 05:22:02 +00:00
Impl (de)serialization for chrono::NaiveDateTime
Adds implementations of `ToXml` and `FromXml` for `chrono::NaiveDateTime`.
This commit is contained in:
parent
35f674ff87
commit
1511976b94
@ -6,7 +6,7 @@ use std::str::FromStr;
|
||||
use std::{any::type_name, marker::PhantomData};
|
||||
|
||||
#[cfg(feature = "chrono")]
|
||||
use chrono::{DateTime, NaiveDate, Utc};
|
||||
use chrono::{DateTime, NaiveDate, NaiveDateTime, Utc};
|
||||
|
||||
use crate::{Accumulate, Deserializer, Error, FromXml, Id, Kind, Serializer, ToXml};
|
||||
|
||||
@ -669,6 +669,68 @@ impl<'xml> FromXml<'xml> for DateTime<Utc> {
|
||||
const KIND: Kind = Kind::Scalar;
|
||||
}
|
||||
|
||||
#[cfg(feature = "chrono")]
|
||||
impl ToXml for NaiveDateTime {
|
||||
fn serialize<W: fmt::Write + ?Sized>(
|
||||
&self,
|
||||
field: Option<Id<'_>>,
|
||||
serializer: &mut Serializer<W>,
|
||||
) -> Result<(), Error> {
|
||||
let prefix = match field {
|
||||
Some(id) => {
|
||||
let prefix = serializer.write_start(id.name, id.ns)?;
|
||||
serializer.end_start()?;
|
||||
Some((prefix, id.name))
|
||||
}
|
||||
None => None,
|
||||
};
|
||||
|
||||
serializer.write_str(&self.format("%Y-%m-%dT%H:%M:%S%.f"))?;
|
||||
if let Some((prefix, name)) = prefix {
|
||||
serializer.write_close(prefix, name)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "chrono")]
|
||||
impl<'xml> FromXml<'xml> for NaiveDateTime {
|
||||
fn matches(id: Id<'_>, field: Option<Id<'_>>) -> bool {
|
||||
match field {
|
||||
Some(field) => id == field,
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn deserialize<'cx>(
|
||||
into: &mut Self::Accumulator,
|
||||
field: &'static str,
|
||||
deserializer: &mut Deserializer<'cx, 'xml>,
|
||||
) -> Result<(), Error> {
|
||||
if into.is_some() {
|
||||
return Err(Error::DuplicateValue(field));
|
||||
}
|
||||
|
||||
let value = match deserializer.take_str()? {
|
||||
Some(value) => value,
|
||||
None => return Ok(()),
|
||||
};
|
||||
|
||||
match NaiveDateTime::parse_from_str(value.as_ref(), "%Y-%m-%dT%H:%M:%S%.f") {
|
||||
Ok(dt) => {
|
||||
*into = Some(dt);
|
||||
Ok(())
|
||||
}
|
||||
_ => Err(Error::Other("invalid date/time".into())),
|
||||
}
|
||||
}
|
||||
|
||||
type Accumulator = Option<Self>;
|
||||
|
||||
const KIND: Kind = Kind::Scalar;
|
||||
}
|
||||
|
||||
#[cfg(feature = "chrono")]
|
||||
impl ToXml for NaiveDate {
|
||||
fn serialize<W: fmt::Write + ?Sized>(
|
||||
|
@ -1,23 +1,36 @@
|
||||
#![cfg(feature = "chrono")]
|
||||
|
||||
use chrono::{DateTime, TimeZone, Utc};
|
||||
use chrono::{DateTime, NaiveDateTime, TimeZone, Utc};
|
||||
use similar_asserts::assert_eq;
|
||||
|
||||
use instant_xml::{from_str, to_string, FromXml, ToXml};
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, FromXml, ToXml)]
|
||||
struct Test {
|
||||
dt: DateTime<Utc>,
|
||||
struct Test<T> {
|
||||
dt: T,
|
||||
}
|
||||
|
||||
type TestUtcDateTime = Test<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);
|
||||
assert_eq!(from_str::<TestUtcDateTime>(xml).unwrap(), test);
|
||||
|
||||
let zulu = xml.replace("+00:00", "Z");
|
||||
assert_eq!(from_str::<Test>(&zulu).unwrap(), test);
|
||||
assert_eq!(from_str::<TestUtcDateTime>(&zulu).unwrap(), test);
|
||||
}
|
||||
|
||||
type TestNaiveDateTime = Test<NaiveDateTime>;
|
||||
|
||||
#[test]
|
||||
fn naive_datetime() {
|
||||
let dt = NaiveDateTime::parse_from_str("2022-11-21T21:17:23", "%Y-%m-%dT%H:%M:%S").unwrap();
|
||||
let test = Test { dt };
|
||||
let xml = "<Test><dt>2022-11-21T21:17:23</dt></Test>";
|
||||
assert_eq!(to_string(&test).unwrap(), xml);
|
||||
assert_eq!(from_str::<TestNaiveDateTime>(xml).unwrap(), test);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user