Skip to content

Commit

Permalink
Merge pull request #51 from martinrlilja/master
Browse files Browse the repository at this point in the history
Added serde support for DateTime, NaiveDate, NaiveTime and NaiveDateTime.
  • Loading branch information
lifthrasiir committed Nov 21, 2015
2 parents 24bc15f + d8f2a3e commit 7153dc0
Show file tree
Hide file tree
Showing 7 changed files with 268 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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" }
83 changes: 83 additions & 0 deletions src/datetime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}
}

2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down
60 changes: 60 additions & 0 deletions src/naive/date.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}
}

/**
Expand Down
59 changes: 59 additions & 0 deletions src/naive/datetime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}
}

59 changes: 59 additions & 0 deletions src/naive/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}
}

0 comments on commit 7153dc0

Please sign in to comment.