Skip to content

Commit

Permalink
Introduce an alloc feature
Browse files Browse the repository at this point in the history
  • Loading branch information
CryZe committed Sep 9, 2019
1 parent 5ccec02 commit 7f10269
Show file tree
Hide file tree
Showing 11 changed files with 82 additions and 20 deletions.
3 changes: 3 additions & 0 deletions .vscode/settings.json
@@ -0,0 +1,3 @@
{
"editor.formatOnSave": false
}
4 changes: 3 additions & 1 deletion Cargo.toml
Expand Up @@ -25,7 +25,9 @@ name = "chrono"

[features]
default = ["clock", "std"]
alloc = []
std = []
serde-1 = ["serde", "alloc"]
clock = ["time", "std"]
wasmbind = ["wasm-bindgen", "js-sys"]

Expand All @@ -34,7 +36,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, optional = true }
serde = { version = "1.0.99", default-features = false, features = ["alloc"], optional = true }

[target.'cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))'.dependencies]
wasm-bindgen = { version = "0.2", optional = true }
Expand Down
3 changes: 3 additions & 0 deletions ci/core-test/Cargo.toml
Expand Up @@ -9,3 +9,6 @@ edition = "2018"

[dependencies]
chrono = { path = "../..", default-features = false, features = ["serde"] }

[features]
alloc = ["chrono/alloc"]
4 changes: 1 addition & 3 deletions ci/travis.sh
Expand Up @@ -123,9 +123,7 @@ build_and_test

CHANNEL=stable
build_and_test
build_core_test

CHANNEL=1.13.0
build_only

CHANNEL=stable
build_core_test
5 changes: 4 additions & 1 deletion src/date.rs
Expand Up @@ -12,7 +12,8 @@ use {Weekday, Datelike};
use offset::{TimeZone, Utc};
use naive::{self, NaiveDate, NaiveTime, IsoWeek};
use DateTime;
use format::{Item, DelayedFormat, StrftimeItems};
#[cfg(any(feature = "alloc", feature = "std", test))]
use format::{DelayedFormat, Item, StrftimeItems};

/// ISO 8601 calendar date with time zone.
///
Expand Down Expand Up @@ -255,6 +256,7 @@ fn map_local<Tz: TimeZone, F>(d: &Date<Tz>, mut f: F) -> Option<Date<Tz>>

impl<Tz: TimeZone> Date<Tz> where Tz::Offset: fmt::Display {
/// Formats the date with the specified formatting items.
#[cfg(any(feature = "alloc", feature = "std", test))]
#[inline]
pub fn format_with_items<'a, I>(&self, items: I) -> DelayedFormat<I>
where I: Iterator<Item=Item<'a>> + Clone {
Expand All @@ -264,6 +266,7 @@ impl<Tz: TimeZone> Date<Tz> where Tz::Offset: fmt::Display {
/// Formats the date with the specified format string.
/// See the [`format::strftime` module](./format/strftime/index.html)
/// on the supported escape sequences.
#[cfg(any(feature = "alloc", feature = "std", test))]
#[inline]
pub fn format<'a>(&self, fmt: &'a str) -> DelayedFormat<StrftimeItems<'a>> {
self.format_with_items(StrftimeItems::new(fmt))
Expand Down
13 changes: 10 additions & 3 deletions src/datetime.rs
Expand Up @@ -10,7 +10,7 @@ use core::ops::{Add, Sub};
use std::time::{SystemTime, UNIX_EPOCH};
use oldtime::Duration as OldDuration;

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

use {Weekday, Timelike, Datelike};
Expand All @@ -20,7 +20,9 @@ use offset::{TimeZone, Offset, Utc, FixedOffset};
use naive::{NaiveTime, NaiveDateTime, IsoWeek};
use Date;
use format::{Item, Numeric, Pad, Fixed};
use format::{parse, Parsed, ParseError, ParseResult, DelayedFormat, StrftimeItems};
use format::{parse, Parsed, ParseError, ParseResult, StrftimeItems};
#[cfg(any(feature = "alloc", feature = "std", test))]
use format::DelayedFormat;

/// Specific formatting options for seconds. This may be extended in the
/// future, so exhaustive matching in external code is not recommended.
Expand Down Expand Up @@ -367,12 +369,14 @@ impl DateTime<FixedOffset> {

impl<Tz: TimeZone> DateTime<Tz> where Tz::Offset: fmt::Display {
/// Returns an RFC 2822 date and time string such as `Tue, 1 Jul 2003 10:52:37 +0200`.
#[cfg(any(feature = "alloc", feature = "std", test))]
pub fn to_rfc2822(&self) -> String {
const ITEMS: &'static [Item<'static>] = &[Item::Fixed(Fixed::RFC2822)];
self.format_with_items(ITEMS.iter().cloned()).to_string()
}

/// Returns an RFC 3339 and ISO 8601 date and time string such as `1996-12-19T16:39:57-08:00`.
#[cfg(any(feature = "alloc", feature = "std", test))]
pub fn to_rfc3339(&self) -> String {
const ITEMS: &'static [Item<'static>] = &[Item::Fixed(Fixed::RFC3339)];
self.format_with_items(ITEMS.iter().cloned()).to_string()
Expand Down Expand Up @@ -402,6 +406,7 @@ impl<Tz: TimeZone> DateTime<Tz> where Tz::Offset: fmt::Display {
/// assert_eq!(dt.to_rfc3339_opts(SecondsFormat::Secs, true),
/// "2018-01-26T10:30:09+08:00");
/// ```
#[cfg(any(feature = "alloc", feature = "std", test))]
pub fn to_rfc3339_opts(&self, secform: SecondsFormat, use_z: bool) -> String {
use format::Numeric::*;
use format::Pad::Zero;
Expand Down Expand Up @@ -453,6 +458,7 @@ impl<Tz: TimeZone> DateTime<Tz> where Tz::Offset: fmt::Display {
}

/// Formats the combined date and time with the specified formatting items.
#[cfg(any(feature = "alloc", feature = "std", test))]
#[inline]
pub fn format_with_items<'a, I>(&self, items: I) -> DelayedFormat<I>
where I: Iterator<Item=Item<'a>> + Clone {
Expand All @@ -463,6 +469,7 @@ impl<Tz: TimeZone> DateTime<Tz> where Tz::Offset: fmt::Display {
/// Formats the combined date and time with the specified format string.
/// See the [`format::strftime` module](./format/strftime/index.html)
/// on the supported escape sequences.
#[cfg(any(feature = "alloc", feature = "std", test))]
#[inline]
pub fn format<'a>(&self, fmt: &'a str) -> DelayedFormat<StrftimeItems<'a>> {
self.format_with_items(StrftimeItems::new(fmt))
Expand Down Expand Up @@ -911,7 +918,7 @@ pub mod rustc_serialize {
}

/// documented at re-export site
#[cfg(feature = "serde")]
#[cfg(feature = "serde-1")]
pub mod serde {
use core::fmt;
#[cfg(not(any(feature = "std", test)))]
Expand Down
38 changes: 36 additions & 2 deletions src/format/mod.rs
Expand Up @@ -21,13 +21,43 @@ use core::fmt;
use core::str::FromStr;
#[cfg(any(feature = "std", test))]
use std::error::Error;
#[cfg(any(feature = "alloc", feature = "std", test))]
use alloc::boxed::Box;
#[cfg(not(any(feature = "std", test)))]
#[cfg(any(feature = "alloc", feature = "std", test))]
use alloc::string::{String, ToString};

use {Datelike, Timelike, Weekday, ParseWeekdayError};
#[cfg(not(any(feature = "alloc", feature = "std", test)))]
mod core_only {
/// Core only
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct Box<T: ?Sized>(core::marker::PhantomData<T>);

impl Box<str> {
/// Core only
pub fn len(&self) -> usize { 0 }
}

impl Clone for Box<str> { fn clone(&self) -> Self { Box(core::marker::PhantomData) } }

impl core::ops::Index<core::ops::RangeFull> for Box<str> {
type Output = str;
fn index(&self, _: core::ops::RangeFull) -> &Self::Output {
""
}
}
}

#[cfg(not(any(feature = "alloc", feature = "std", test)))]
use self::core_only::Box;

#[cfg(any(feature = "alloc", feature = "std", test))]
use {Datelike, Timelike};
use {Weekday, ParseWeekdayError};
#[cfg(any(feature = "alloc", feature = "std", test))]
use div::{div_floor, mod_floor};
#[cfg(any(feature = "alloc", feature = "std", test))]
use offset::{Offset, FixedOffset};
#[cfg(any(feature = "alloc", feature = "std", test))]
use naive::{NaiveDate, NaiveTime};

pub use self::strftime::StrftimeItems;
Expand Down Expand Up @@ -347,6 +377,7 @@ const BAD_FORMAT: ParseError = ParseError(ParseErrorKind::BadFormat);

/// Tries to format given arguments with given formatting items.
/// Internally used by `DelayedFormat`.
#[cfg(any(feature = "alloc", feature = "std", test))]
pub fn format<'a, I>(
w: &mut fmt::Formatter,
date: Option<&NaiveDate>,
Expand Down Expand Up @@ -609,6 +640,7 @@ pub mod strftime;

/// A *temporary* object which can be used as an argument to `format!` or others.
/// This is normally constructed via `format` methods of each date and time type.
#[cfg(any(feature = "alloc", feature = "std", test))]
#[derive(Debug)]
pub struct DelayedFormat<I> {
/// The date view, if any.
Expand All @@ -621,6 +653,7 @@ pub struct DelayedFormat<I> {
items: I,
}

#[cfg(any(feature = "alloc", feature = "std", test))]
impl<'a, I: Iterator<Item=Item<'a>> + Clone> DelayedFormat<I> {
/// Makes a new `DelayedFormat` value out of local date and time.
pub fn new(date: Option<NaiveDate>, time: Option<NaiveTime>, items: I) -> DelayedFormat<I> {
Expand All @@ -636,6 +669,7 @@ impl<'a, I: Iterator<Item=Item<'a>> + Clone> DelayedFormat<I> {
}
}

#[cfg(any(feature = "alloc", feature = "std", test))]
impl<'a, I: Iterator<Item=Item<'a>> + Clone> fmt::Display for DelayedFormat<I> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
format(f, self.date.as_ref(), self.time.as_ref(), self.off.as_ref(), self.items.clone())
Expand Down
8 changes: 4 additions & 4 deletions src/lib.rs
Expand Up @@ -418,7 +418,7 @@ extern crate num_integer;
extern crate num_traits;
#[cfg(feature = "rustc-serialize")]
extern crate rustc_serialize;
#[cfg(feature = "serde")]
#[cfg(feature = "serde-1")]
extern crate serde as serdelib;
#[cfg(test)]
#[macro_use]
Expand Down Expand Up @@ -497,7 +497,7 @@ pub mod naive {
///
/// [1]: https://serde.rs/attributes.html#field-attributes
/// [2]: https://tools.ietf.org/html/rfc3339
#[cfg(feature = "serde")]
#[cfg(feature = "serde-1")]
pub mod serde {
pub use super::datetime::serde::*;
}
Expand All @@ -515,7 +515,7 @@ mod round;
///
/// [1]: https://serde.rs/attributes.html#field-attributes
/// [2]: https://tools.ietf.org/html/rfc3339
#[cfg(feature = "serde")]
#[cfg(feature = "serde-1")]
pub mod serde {
pub use super::datetime::serde::*;
}
Expand Down Expand Up @@ -703,7 +703,7 @@ impl fmt::Debug for ParseWeekdayError {

// the actual `FromStr` implementation is in the `format` module to leverage the existing code

#[cfg(feature = "serde")]
#[cfg(feature = "serde-1")]
mod weekday_serde {
use super::Weekday;
use core::fmt;
Expand Down
8 changes: 6 additions & 2 deletions src/naive/date.rs
Expand Up @@ -12,7 +12,9 @@ use {Weekday, Datelike};
use div::div_mod_floor;
use naive::{NaiveTime, NaiveDateTime, IsoWeek};
use format::{Item, Numeric, Pad};
use format::{parse, Parsed, ParseError, ParseResult, DelayedFormat, StrftimeItems};
use format::{parse, Parsed, ParseError, ParseResult, StrftimeItems};
#[cfg(any(feature = "alloc", feature = "std", test))]
use format::DelayedFormat;

use super::isoweek;
use super::internals::{self, DateImpl, Of, Mdf, YearFlags};
Expand Down Expand Up @@ -916,6 +918,7 @@ impl NaiveDate {
/// # let d = NaiveDate::from_ymd(2015, 9, 5);
/// assert_eq!(format!("{}", d.format_with_items(fmt)), "2015-09-05");
/// ~~~~
#[cfg(any(feature = "alloc", feature = "std", test))]
#[inline]
pub fn format_with_items<'a, I>(&self, items: I) -> DelayedFormat<I>
where I: Iterator<Item=Item<'a>> + Clone {
Expand Down Expand Up @@ -954,6 +957,7 @@ impl NaiveDate {
/// assert_eq!(format!("{}", d.format("%Y-%m-%d")), "2015-09-05");
/// assert_eq!(format!("{}", d.format("%A, %-d %B, %C%y")), "Saturday, 5 September, 2015");
/// ~~~~
#[cfg(any(feature = "alloc", feature = "std", test))]
#[inline]
pub fn format<'a>(&self, fmt: &'a str) -> DelayedFormat<StrftimeItems<'a>> {
self.format_with_items(StrftimeItems::new(fmt))
Expand Down Expand Up @@ -1598,7 +1602,7 @@ mod rustc_serialize {
}
}

#[cfg(feature = "serde")]
#[cfg(feature = "serde-1")]
mod serde {
use core::fmt;
#[cfg(not(any(feature = "std", test)))]
Expand Down
8 changes: 6 additions & 2 deletions src/naive/datetime.rs
Expand Up @@ -12,7 +12,9 @@ use {Weekday, Timelike, Datelike};
use div::div_mod_floor;
use naive::{NaiveTime, NaiveDate, IsoWeek};
use format::{Item, Numeric, Pad, Fixed};
use format::{parse, Parsed, ParseError, ParseResult, DelayedFormat, StrftimeItems};
use format::{parse, Parsed, ParseError, ParseResult, StrftimeItems};
#[cfg(any(feature = "alloc", feature = "std", test))]
use format::DelayedFormat;

/// The tight upper bound guarantees that a duration with `|Duration| >= 2^MAX_SECS_BITS`
/// will always overflow the addition with any date and time type.
Expand Down Expand Up @@ -645,6 +647,7 @@ impl NaiveDateTime {
/// # let dt = NaiveDate::from_ymd(2015, 9, 5).and_hms(23, 56, 4);
/// assert_eq!(format!("{}", dt.format_with_items(fmt)), "2015-09-05 23:56:04");
/// ~~~~
#[cfg(any(feature = "alloc", feature = "std", test))]
#[inline]
pub fn format_with_items<'a, I>(&self, items: I) -> DelayedFormat<I>
where I: Iterator<Item=Item<'a>> + Clone {
Expand Down Expand Up @@ -683,6 +686,7 @@ impl NaiveDateTime {
/// assert_eq!(format!("{}", dt.format("%Y-%m-%d %H:%M:%S")), "2015-09-05 23:56:04");
/// assert_eq!(format!("{}", dt.format("around %l %p on %b %-d")), "around 11 PM on Sep 5");
/// ~~~~
#[cfg(any(feature = "alloc", feature = "std", test))]
#[inline]
pub fn format<'a>(&self, fmt: &'a str) -> DelayedFormat<StrftimeItems<'a>> {
self.format_with_items(StrftimeItems::new(fmt))
Expand Down Expand Up @@ -1661,7 +1665,7 @@ pub mod rustc_serialize {
}

/// Tools to help serializing/deserializing `NaiveDateTime`s
#[cfg(feature = "serde")]
#[cfg(feature = "serde-1")]
pub mod serde {
use core::fmt;
#[cfg(not(any(feature = "std", test)))]
Expand Down
8 changes: 6 additions & 2 deletions src/naive/time.rs
Expand Up @@ -10,7 +10,9 @@ use oldtime::Duration as OldDuration;
use Timelike;
use div::div_mod_floor;
use format::{Item, Numeric, Pad, Fixed};
use format::{parse, Parsed, ParseError, ParseResult, DelayedFormat, StrftimeItems};
use format::{parse, Parsed, ParseError, ParseResult, StrftimeItems};
#[cfg(any(feature = "alloc", feature = "std", test))]
use format::DelayedFormat;

/// ISO 8601 time without timezone.
/// Allows for the nanosecond precision and optional leap second representation.
Expand Down Expand Up @@ -723,6 +725,7 @@ impl NaiveTime {
/// # let t = NaiveTime::from_hms(23, 56, 4);
/// assert_eq!(format!("{}", t.format_with_items(fmt)), "23:56:04");
/// ~~~~
#[cfg(any(feature = "alloc", feature = "std", test))]
#[inline]
pub fn format_with_items<'a, I>(&self, items: I) -> DelayedFormat<I>
where I: Iterator<Item=Item<'a>> + Clone {
Expand Down Expand Up @@ -763,6 +766,7 @@ impl NaiveTime {
/// assert_eq!(format!("{}", t.format("%H:%M:%S%.6f")), "23:56:04.012345");
/// assert_eq!(format!("{}", t.format("%-I:%M %p")), "11:56 PM");
/// ~~~~
#[cfg(any(feature = "alloc", feature = "std", test))]
#[inline]
pub fn format<'a>(&self, fmt: &'a str) -> DelayedFormat<StrftimeItems<'a>> {
self.format_with_items(StrftimeItems::new(fmt))
Expand Down Expand Up @@ -1409,7 +1413,7 @@ mod rustc_serialize {
}
}

#[cfg(feature = "serde")]
#[cfg(feature = "serde-1")]
mod serde {
use core::fmt;
#[cfg(not(any(feature = "std", test)))]
Expand Down

0 comments on commit 7f10269

Please sign in to comment.