Skip to content

Commit

Permalink
First pass at making "alloc" its own feature
Browse files Browse the repository at this point in the history
Part of this means that we don't actually need to allocate to write to Serde
any more, which is a win in its own right.
  • Loading branch information
quodlibetor committed Sep 16, 2019
1 parent 5b72ef3 commit e5bbc94
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 22 deletions.
4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ name = "chrono"
default = ["clock", "std"]
alloc = []
std = []
serde_alloc = ["serde/alloc"]
serde_std = ["serde/std"]
clock = ["time", "std"]
wasmbind = ["wasm-bindgen", "js-sys"]

Expand All @@ -35,7 +37,7 @@ time = { version = "0.1.39", optional = true }
num-integer = { version = "0.1.36", default-features = false }
num-traits = { version = "0.2", default-features = false }
rustc-serialize = { version = "0.3.20", optional = true }
serde = { version = "1.0.99", default-features = false, features = ["alloc"], optional = true }
serde = { version = "1.0.99", default-features = false, optional = true }

[target.'cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))'.dependencies]
wasm-bindgen = { version = "0.2", optional = true }
Expand Down
46 changes: 36 additions & 10 deletions src/datetime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ use core::ops::{Add, Sub};
use std::time::{SystemTime, UNIX_EPOCH};
use oldtime::Duration as OldDuration;

#[cfg(any(feature = "alloc", feature = "std", test))]
#[cfg(all(not(feature = "std"), feature = "alloc"))]
use alloc::string::{String, ToString};
#[cfg(feature = "std")]
use std::string::ToString;

use {Weekday, Timelike, Datelike};
#[cfg(feature="clock")]
Expand Down Expand Up @@ -921,26 +923,50 @@ pub mod rustc_serialize {
#[cfg(feature = "serde")]
pub mod serde {
use core::fmt;
#[cfg(not(any(feature = "std", test)))]
use alloc::format;
// #[cfg(any(test, feature = "alloc"))]
// use alloc::format;
use super::DateTime;
#[cfg(feature="clock")]
use offset::Local;
use offset::{LocalResult, TimeZone, Utc, FixedOffset};
use serdelib::{ser, de};

enum SerdeError<V: fmt::Display, D: fmt::Display> {
NonExistent { timestamp: V },
Ambiguous { timestamp: V, min: D, max: D }
}

impl<V: fmt::Display, D: fmt::Display> fmt::Debug for SerdeError<V, D> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "ChronoSerdeError({})", self)
}
}

// impl<V: fmt::Display, D: fmt::Debug> core::error::Error for SerdeError<V, D> {}
impl<V: fmt::Display, D: fmt::Display> fmt::Display for SerdeError<V, D> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
&SerdeError::NonExistent { ref timestamp } => write!(
f, "value is not a legal timestamp: {}", timestamp),
&SerdeError::Ambiguous { ref timestamp, ref min, ref max } => write!(
f, "value is an ambiguous timestamp: {}, could be either of {}, {}",
timestamp, min, max),
}
}
}

// try!-like function to convert a LocalResult into a serde-ish Result
fn serde_from<T, E, V>(me: LocalResult<T>, ts: &V) -> Result<T, E>
where E: de::Error,
V: fmt::Display,
T: fmt::Display,
where
E: de::Error,
V: fmt::Display,
T: fmt::Display,
{
match me {
LocalResult::None => Err(E::custom(
format!("value is not a legal timestamp: {}", ts))),
SerdeError::NonExistent::<_, u8> { timestamp: ts })),
LocalResult::Ambiguous(min, max) => Err(E::custom(
format!("value is an ambiguous timestamp: {}, could be either of {}, {}",
ts, min, max))),
SerdeError::Ambiguous { timestamp: ts, min: min, max: max })),
LocalResult::Single(val) => Ok(val)
}
}
Expand Down Expand Up @@ -1418,7 +1444,7 @@ pub mod serde {
fn visit_str<E>(self, value: &str) -> Result<DateTime<FixedOffset>, E>
where E: de::Error
{
value.parse().map_err(|err| E::custom(format!("{}", err)))
value.parse().map_err(|err: ::format::ParseError| E::custom(err))
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/format/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ use core::fmt;
use core::str::FromStr;
#[cfg(any(feature = "std", test))]
use std::error::Error;
#[cfg(any(feature = "alloc", feature = "std", test))]
#[cfg(feature = "alloc")]
use alloc::boxed::Box;
#[cfg(any(feature = "alloc", feature = "std", test))]
#[cfg(feature = "alloc")]
use alloc::string::{String, ToString};

#[cfg(not(any(feature = "alloc", feature = "std", test)))]
Expand Down
22 changes: 17 additions & 5 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -405,11 +405,11 @@
trivially_copy_pass_by_ref,
))]

#[cfg(not(any(feature = "std", test)))]
#[cfg(feature = "alloc")]
extern crate alloc;
#[cfg(any(feature = "std", test))]
extern crate std as core;
#[cfg(any(feature = "std", test))]
#[cfg(all(feature = "std", not(feature="alloc")))]
extern crate std as alloc;

#[cfg(feature="clock")]
Expand Down Expand Up @@ -654,6 +654,20 @@ impl Weekday {
}
}

impl fmt::Display for Weekday {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str(match *self {
Weekday::Mon => "Mon",
Weekday::Tue => "Tue",
Weekday::Wed => "Wed",
Weekday::Thu => "Thu",
Weekday::Fri => "Fri",
Weekday::Sat => "Sat",
Weekday::Sun => "Sun",
})
}
}

/// Any weekday can be represented as an integer from 0 to 6, which equals to
/// [`Weekday::num_days_from_monday`](#method.num_days_from_monday) in this implementation.
/// Do not heavily depend on this though; use explicit methods whenever possible.
Expand Down Expand Up @@ -707,15 +721,13 @@ impl fmt::Debug for ParseWeekdayError {
mod weekday_serde {
use super::Weekday;
use core::fmt;
#[cfg(not(any(feature = "std", test)))]
use alloc::format;
use serdelib::{ser, de};

impl ser::Serialize for Weekday {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: ser::Serializer
{
serializer.serialize_str(&format!("{:?}", self))
serializer.collect_str(&self)
}
}

Expand Down
10 changes: 8 additions & 2 deletions src/naive/date.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1605,8 +1605,6 @@ mod rustc_serialize {
#[cfg(feature = "serde")]
mod serde {
use core::fmt;
#[cfg(not(any(feature = "std", test)))]
use alloc::format;
use super::NaiveDate;
use serdelib::{ser, de};

Expand Down Expand Up @@ -1640,11 +1638,19 @@ mod serde {
write!(formatter, "a formatted date string")
}

#[cfg(any(feature = "std", test))]
fn visit_str<E>(self, value: &str) -> Result<NaiveDate, E>
where E: de::Error
{
value.parse().map_err(|err| E::custom(format!("{}", err)))
}

#[cfg(not(any(feature = "std", test)))]
fn visit_str<E>(self, value: &str) -> Result<NaiveDate, E>
where E: de::Error
{
value.parse().map_err(|err| E::custom(err))
}
}

impl<'de> de::Deserialize<'de> for NaiveDate {
Expand Down
2 changes: 1 addition & 1 deletion src/naive/datetime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1668,7 +1668,7 @@ pub mod rustc_serialize {
#[cfg(feature = "serde")]
pub mod serde {
use core::fmt;
#[cfg(not(any(feature = "std", test)))]
#[cfg(feature = "alloc")]
use alloc::format;
use super::{NaiveDateTime};
use serdelib::{ser, de};
Expand Down
2 changes: 1 addition & 1 deletion src/naive/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1416,7 +1416,7 @@ mod rustc_serialize {
#[cfg(feature = "serde")]
mod serde {
use core::fmt;
#[cfg(not(any(feature = "std", test)))]
#[cfg(feature = "alloc")]
use alloc::format;
use super::NaiveTime;
use serdelib::{ser, de};
Expand Down

0 comments on commit e5bbc94

Please sign in to comment.