Added serde support for DateTime, NaiveDate, NaiveTime and NaiveDateTime.

This commit is contained in:
Martin Risell Lilja 2015-11-09 15:26:36 +01:00
parent 24bc15fdd3
commit d8f2a3e7d8
7 changed files with 268 additions and 0 deletions

View File

@ -9,8 +9,10 @@ env:
script:
- cargo build -v
- cargo build -v --features rustc-serialize
- cargo build -v --features serde
- cargo test -v
- cargo test -v --features rustc-serialize
- cargo test -v --features serde
- cargo doc
after_script:
- cd target && curl http://www.rust-ci.org/artifacts/put?t=$RUSTCI_TOKEN | sh

View File

@ -18,4 +18,7 @@ name = "chrono"
time = "*"
num = "*"
rustc-serialize = { version = "0.3", optional = true }
serde = { version = "^0.6.0", optional = true }
[dev-dependencies]
serde_json = { version = "^0.6.0" }

View File

@ -366,6 +366,64 @@ impl str::FromStr for DateTime<Local> {
}
}
#[cfg(feature = "serde")]
mod serde {
use super::DateTime;
use offset::TimeZone;
use offset::utc::UTC;
use offset::local::Local;
use offset::fixed::FixedOffset;
use std::fmt::Display;
use serde::{ser, de};
impl<Tz: TimeZone> ser::Serialize for DateTime<Tz>
where Tz::Offset: Display
{
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: ser::Serializer
{
// Debug formatting is correct RFC3339, and it allows Zulu.
serializer.visit_str(&format!("{:?}", self))
}
}
struct DateTimeVisitor;
impl de::Visitor for DateTimeVisitor {
type Value = DateTime<FixedOffset>;
fn visit_str<E>(&mut self, value: &str) -> Result<DateTime<FixedOffset>, E>
where E: de::Error
{
value.parse().map_err(|err| E::syntax(&format!("{}", err)))
}
}
impl de::Deserialize for DateTime<FixedOffset> {
fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error>
where D: de::Deserializer
{
deserializer.visit(DateTimeVisitor)
}
}
impl de::Deserialize for DateTime<UTC> {
fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error>
where D: de::Deserializer
{
deserializer.visit(DateTimeVisitor).map(|dt| dt.with_timezone(&UTC))
}
}
impl de::Deserialize for DateTime<Local> {
fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error>
where D: de::Deserializer
{
deserializer.visit(DateTimeVisitor).map(|dt| dt.with_timezone(&Local))
}
}
}
#[cfg(test)]
mod tests {
use super::DateTime;
@ -518,5 +576,30 @@ mod tests {
let _ = a;
}).join().unwrap();
}
#[cfg(feature = "serde")]
extern crate serde_json;
#[cfg(feature = "serde")]
#[test]
fn test_serde_serialize() {
use self::serde_json::to_string;
let date = UTC.ymd(2014, 7, 24).and_hms(12, 34, 6);
let serialized = to_string(&date).unwrap();
assert_eq!(serialized, "\"2014-07-24T12:34:06Z\"");
}
#[cfg(feature = "serde")]
#[test]
fn test_serde_deserialize() {
use self::serde_json::from_str;
let date = UTC.ymd(2014, 7, 24).and_hms(12, 34, 6);
let deserialized: DateTime<UTC> = from_str("\"2014-07-24T12:34:06Z\"").unwrap();
assert_eq!(deserialized, date);
}
}

View File

@ -275,6 +275,8 @@ extern crate time as stdtime;
extern crate num;
#[cfg(feature = "rustc-serialize")]
extern crate rustc_serialize;
#[cfg(feature = "serde")]
extern crate serde;
pub use duration::Duration;
pub use offset::{TimeZone, Offset, LocalResult};

View File

@ -1051,6 +1051,41 @@ impl str::FromStr for NaiveDate {
}
}
#[cfg(feature = "serde")]
mod serde {
use super::NaiveDate;
use serde::{ser, de};
impl ser::Serialize for NaiveDate {
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: ser::Serializer
{
serializer.visit_str(&format!("{:?}", self))
}
}
struct NaiveDateVisitor;
impl de::Visitor for NaiveDateVisitor {
type Value = NaiveDate;
fn visit_str<E>(&mut self, value: &str) -> Result<NaiveDate, E>
where E: de::Error
{
value.parse().map_err(|err| E::syntax(&format!("{}", err)))
}
}
impl de::Deserialize for NaiveDate {
fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error>
where D: de::Deserializer
{
deserializer.visit(NaiveDateVisitor)
}
}
}
#[cfg(test)]
mod tests {
use super::NaiveDate;
@ -1477,6 +1512,31 @@ mod tests {
assert_eq!(NaiveDate::from_ymd(2010, 1, 3).format("%G,%g,%U,%W,%V").to_string(),
"2009,09,01,00,53");
}
#[cfg(feature = "serde")]
extern crate serde_json;
#[cfg(feature = "serde")]
#[test]
fn test_serde_serialize() {
use self::serde_json::to_string;
let date = NaiveDate::from_ymd(2014, 7, 24);
let serialized = to_string(&date).unwrap();
assert_eq!(serialized, "\"2014-07-24\"");
}
#[cfg(feature = "serde")]
#[test]
fn test_serde_deserialize() {
use self::serde_json::from_str;
let date = NaiveDate::from_ymd(2014, 7, 24);
let deserialized: NaiveDate = from_str("\"2014-07-24\"").unwrap();
assert_eq!(deserialized, date);
}
}
/**

View File

@ -315,6 +315,40 @@ impl str::FromStr for NaiveDateTime {
}
}
#[cfg(feature = "serde")]
mod serde {
use super::NaiveDateTime;
use serde::{ser, de};
impl ser::Serialize for NaiveDateTime {
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: ser::Serializer
{
serializer.visit_str(&format!("{:?}", self))
}
}
struct NaiveDateTimeVisitor;
impl de::Visitor for NaiveDateTimeVisitor {
type Value = NaiveDateTime;
fn visit_str<E>(&mut self, value: &str) -> Result<NaiveDateTime, E>
where E: de::Error
{
value.parse().map_err(|err| E::syntax(&format!("{}", err)))
}
}
impl de::Deserialize for NaiveDateTime {
fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error>
where D: de::Deserializer
{
deserializer.visit(NaiveDateTimeVisitor)
}
}
}
#[cfg(test)]
mod tests {
use super::NaiveDateTime;
@ -468,5 +502,30 @@ mod tests {
let time = base + Duration::microseconds(t);
assert_eq!(t, (time - base).num_microseconds().unwrap());
}
#[cfg(feature = "serde")]
extern crate serde_json;
#[cfg(feature = "serde")]
#[test]
fn test_serde_serialize() {
use self::serde_json::to_string;
let date = NaiveDate::from_ymd(2014, 7, 24).and_hms(12, 34, 6);
let serialized = to_string(&date).unwrap();
assert_eq!(serialized, "\"2014-07-24T12:34:06\"");
}
#[cfg(feature = "serde")]
#[test]
fn test_serde_deserialize() {
use self::serde_json::from_str;
let date = NaiveDate::from_ymd(2014, 7, 24).and_hms(12, 34, 6);
let deserialized: NaiveDateTime = from_str("\"2014-07-24T12:34:06\"").unwrap();
assert_eq!(deserialized, date);
}
}

View File

@ -574,6 +574,40 @@ impl str::FromStr for NaiveTime {
}
}
#[cfg(feature = "serde")]
mod serde {
use super::NaiveTime;
use serde::{ser, de};
impl ser::Serialize for NaiveTime {
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: ser::Serializer
{
serializer.visit_str(&format!("{:?}", self))
}
}
struct NaiveTimeVisitor;
impl de::Visitor for NaiveTimeVisitor {
type Value = NaiveTime;
fn visit_str<E>(&mut self, value: &str) -> Result<NaiveTime, E>
where E: de::Error
{
value.parse().map_err(|err| E::syntax(&format!("{}", err)))
}
}
impl de::Deserialize for NaiveTime {
fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error>
where D: de::Deserializer
{
deserializer.visit(NaiveTimeVisitor)
}
}
}
#[cfg(test)]
mod tests {
use super::NaiveTime;
@ -764,5 +798,30 @@ mod tests {
assert_eq!(NaiveTime::from_hms_milli(23, 59, 59, 1_000).format("%X").to_string(),
"23:59:60");
}
#[cfg(feature = "serde")]
extern crate serde_json;
#[cfg(feature = "serde")]
#[test]
fn test_serde_serialize() {
use self::serde_json::to_string;
let time = NaiveTime::from_hms_nano(3, 5, 7, 98765432);
let serialized = to_string(&time).unwrap();
assert_eq!(serialized, "\"03:05:07.098765432\"");
}
#[cfg(feature = "serde")]
#[test]
fn test_serde_deserialize() {
use self::serde_json::from_str;
let time = NaiveTime::from_hms_nano(3, 5, 7, 98765432);
let deserialized: NaiveTime = from_str("\"03:05:07.098765432\"").unwrap();
assert_eq!(deserialized, time);
}
}