Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Support for no_std #341

Merged
merged 15 commits into from
Nov 22, 2019
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,17 @@ appveyor = { repository = "chronotope/chrono" }
name = "chrono"

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

[dependencies]
libc = { version = "0.2", default-features = false }
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", 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
11 changes: 11 additions & 0 deletions ci/core-test/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[package]
name = "core-test"
version = "0.1.0"
authors = [
"Kang Seonghoon <public+rust@mearie.org>",
"Brandon W Maister <quodlibetor@gmail.com>",
]
edition = "2018"

[dependencies]
chrono = { path = "../..", default-features = false, features = ["serde"] }
1 change: 1 addition & 0 deletions ci/core-test/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#![no_std]
22 changes: 16 additions & 6 deletions ci/travis.sh
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,14 @@ build_and_test_nonwasm() {
TZ=Asia/Katmandu channel test -v --features serde,rustc-serialize

# without default "clock" feature
channel build -v --no-default-features
channel build -v --no-default-features --features std
TZ=ACST-9:30 channel test -v --no-default-features --lib
channel build -v --no-default-features --features rustc-serialize
channel build -v --no-default-features --features std,rustc-serialize
TZ=EST4 channel test -v --no-default-features --features rustc-serialize --lib
channel build -v --no-default-features --features serde
channel build -v --no-default-features --features std,serde
TZ=UTC0 channel test -v --no-default-features --features serde --lib
channel build -v --no-default-features --features serde,rustc-serialize
TZ=Asia/Katmandu channel test -v --no-default-features --features serde,rustc-serialize --lib
channel build -v --no-default-features --features std,serde,rustc-serialize
TZ=Asia/Katmandu channel test -v --no-default-features --features std,serde,rustc-serialize --lib
}

build_and_test_wasm() {
Expand All @@ -82,7 +82,14 @@ build_only() {
channel build -v
channel build -v --features rustc-serialize
channel build -v --features 'serde bincode'
channel build -v --no-default-features
channel build -v --no-default-features --features std
}

build_core_test() {
rustup target add thumbv6m-none-eabi --toolchain $CHANNEL
cd ci/core-test
channel build -v --target thumbv6m-none-eabi
cd ../..
}

run_clippy() {
Expand Down Expand Up @@ -119,3 +126,6 @@ build_and_test

CHANNEL=1.13.0
build_only

CHANNEL=stable
build_core_test
CryZe marked this conversation as resolved.
Show resolved Hide resolved
6 changes: 3 additions & 3 deletions src/date.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@

//! ISO 8601 calendar date with time zone.

use std::{fmt, hash};
use std::cmp::Ordering;
use std::ops::{Add, Sub};
use core::{fmt, hash};
use core::cmp::Ordering;
use core::ops::{Add, Sub};
use oldtime::Duration as OldDuration;

use {Weekday, Datelike};
Expand Down
32 changes: 20 additions & 12 deletions src/datetime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,16 @@

//! ISO 8601 date and time with time zone.

use std::{str, fmt, hash};
use std::cmp::Ordering;
use std::ops::{Add, Sub};
use core::{str, fmt, hash};
use core::cmp::Ordering;
use core::ops::{Add, Sub};
#[cfg(any(feature = "std", test))]
use std::time::{SystemTime, UNIX_EPOCH};
use oldtime::Duration as OldDuration;

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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like it might be worth sticking this (and what seems like the two functions that return strings) behind a separate alloc feature flag?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added an alloc feature now. I'm kind of sad how much is missing without it though. And it's mostly only because the timezone offset is stored as a String in the DelayedFormat.


use {Weekday, Timelike, Datelike};
#[cfg(feature="clock")]
use offset::Local;
Expand Down Expand Up @@ -647,6 +651,7 @@ impl str::FromStr for DateTime<Local> {
}
}

#[cfg(any(feature = "std", test))]
impl From<SystemTime> for DateTime<Utc> {
fn from(t: SystemTime) -> DateTime<Utc> {
let (sec, nsec) = match t.duration_since(UNIX_EPOCH) {
Expand All @@ -672,6 +677,7 @@ impl From<SystemTime> for DateTime<Local> {
}
}

#[cfg(any(feature = "std", test))]
impl<Tz: TimeZone> From<DateTime<Tz>> for SystemTime {
fn from(dt: DateTime<Tz>) -> SystemTime {
use std::time::Duration;
Expand Down Expand Up @@ -699,7 +705,7 @@ fn test_auto_conversion() {
fn test_encodable_json<FUtc, FFixed, E>(to_string_utc: FUtc, to_string_fixed: FFixed)
where FUtc: Fn(&DateTime<Utc>) -> Result<String, E>,
FFixed: Fn(&DateTime<FixedOffset>) -> Result<String, E>,
E: ::std::fmt::Debug
E: ::core::fmt::Debug
{
assert_eq!(to_string_utc(&Utc.ymd(2014, 7, 24).and_hms(12, 34, 6)).ok(),
Some(r#""2014-07-24T12:34:06Z""#.into()));
Expand All @@ -717,7 +723,7 @@ fn test_decodable_json<FUtc, FFixed, FLocal, E>(utc_from_str: FUtc,
where FUtc: Fn(&str) -> Result<DateTime<Utc>, E>,
FFixed: Fn(&str) -> Result<DateTime<FixedOffset>, E>,
FLocal: Fn(&str) -> Result<DateTime<Local>, E>,
E: ::std::fmt::Debug
E: ::core::fmt::Debug
{
// should check against the offset as well (the normal DateTime comparison will ignore them)
fn norm<Tz: TimeZone>(dt: &Option<DateTime<Tz>>) -> Option<(&DateTime<Tz>, &Tz::Offset)> {
Expand Down Expand Up @@ -754,7 +760,7 @@ fn test_decodable_json_timestamps<FUtc, FFixed, FLocal, E>(utc_from_str: FUtc,
where FUtc: Fn(&str) -> Result<rustc_serialize::TsSeconds<Utc>, E>,
FFixed: Fn(&str) -> Result<rustc_serialize::TsSeconds<FixedOffset>, E>,
FLocal: Fn(&str) -> Result<rustc_serialize::TsSeconds<Local>, E>,
E: ::std::fmt::Debug
E: ::core::fmt::Debug
{
fn norm<Tz: TimeZone>(dt: &Option<DateTime<Tz>>) -> Option<(&DateTime<Tz>, &Tz::Offset)> {
dt.as_ref().map(|dt| (dt, dt.offset()))
Expand All @@ -778,8 +784,8 @@ fn test_decodable_json_timestamps<FUtc, FFixed, FLocal, E>(utc_from_str: FUtc,

#[cfg(feature = "rustc-serialize")]
pub mod rustc_serialize {
use std::fmt;
use std::ops::Deref;
use core::fmt;
use core::ops::Deref;
use super::DateTime;
#[cfg(feature="clock")]
use offset::Local;
Expand Down Expand Up @@ -907,7 +913,9 @@ pub mod rustc_serialize {
/// documented at re-export site
#[cfg(feature = "serde")]
pub mod serde {
use std::fmt;
use core::fmt;
#[cfg(not(any(feature = "std", test)))]
use alloc::format;
use super::DateTime;
#[cfg(feature="clock")]
use offset::Local;
Expand Down Expand Up @@ -967,7 +975,7 @@ pub mod serde {
/// # fn main() { example().unwrap(); }
/// ```
pub mod ts_nanoseconds {
use std::fmt;
use core::fmt;
use serdelib::{ser, de};

use {DateTime, Utc};
Expand Down Expand Up @@ -1114,7 +1122,7 @@ pub mod serde {
/// # fn main() { example().unwrap(); }
/// ```
pub mod ts_milliseconds {
use std::fmt;
use core::fmt;
use serdelib::{ser, de};

use {DateTime, Utc};
Expand Down Expand Up @@ -1261,7 +1269,7 @@ pub mod serde {
/// # fn main() { example().unwrap(); }
/// ```
pub mod ts_seconds {
use std::fmt;
use core::fmt;
use serdelib::{ser, de};

use {DateTime, Utc};
Expand Down
39 changes: 25 additions & 14 deletions src/format/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,13 @@

#![allow(ellipsis_inclusive_range_patterns)]

use std::fmt;
use std::str::FromStr;
use core::fmt;
use core::str::FromStr;
#[cfg(any(feature = "std", test))]
use std::error::Error;
use alloc::boxed::Box;
#[cfg(not(any(feature = "std", test)))]
use alloc::string::{String, ToString};

use {Datelike, Timelike, Weekday, ParseWeekdayError};
use div::{div_floor, mod_floor};
Expand All @@ -30,7 +34,7 @@ pub use self::strftime::StrftimeItems;
pub use self::parsed::Parsed;
pub use self::parse::parse;

/// An unhabitated type used for `InternalNumeric` and `InternalFixed` below.
/// An uninhabited type used for `InternalNumeric` and `InternalFixed` below.
#[derive(Clone, PartialEq, Eq)]
enum Void {}

Expand All @@ -55,7 +59,7 @@ pub enum Pad {
///
/// The **parsing width** is the maximal width to be scanned.
/// The parser only tries to consume from one to given number of digits (greedily).
/// It also trims the preceding whitespaces if any.
/// It also trims the preceding whitespace if any.
/// It cannot parse the negative number, so some date and time cannot be formatted then
/// parsed with the same formatting items.
#[derive(Clone, PartialEq, Eq, Debug)]
Expand Down Expand Up @@ -185,13 +189,13 @@ pub enum Fixed {
TimezoneName,
/// Offset from the local time to UTC (`+09:00` or `-04:00` or `+00:00`).
///
/// In the parser, the colon can be omitted and/or surrounded with any amount of whitespaces.
/// In the parser, the colon can be omitted and/or surrounded with any amount of whitespace.
/// The offset is limited from `-24:00` to `+24:00`,
/// which is same to [`FixedOffset`](../offset/struct.FixedOffset.html)'s range.
TimezoneOffsetColon,
/// Offset from the local time to UTC (`+09:00` or `-04:00` or `Z`).
///
/// In the parser, the colon can be omitted and/or surrounded with any amount of whitespaces,
/// In the parser, the colon can be omitted and/or surrounded with any amount of whitespace,
/// and `Z` can be either in upper case or in lower case.
/// The offset is limited from `-24:00` to `+24:00`,
/// which is same to [`FixedOffset`](../offset/struct.FixedOffset.html)'s range.
Expand Down Expand Up @@ -305,13 +309,7 @@ enum ParseErrorKind {
/// Same to `Result<T, ParseError>`.
pub type ParseResult<T> = Result<T, ParseError>;

impl fmt::Display for ParseError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.description().fmt(f)
}
}

impl Error for ParseError {
impl ParseError {
fn description(&self) -> &str {
match self.0 {
ParseErrorKind::OutOfRange => "input is out of range",
Expand All @@ -325,6 +323,19 @@ impl Error for ParseError {
}
}

impl fmt::Display for ParseError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.description().fmt(f)
}
}

#[cfg(any(feature = "std", test))]
impl Error for ParseError {
fn description(&self) -> &str {
self.description()
}
}

// to be used in this module and submodules
const OUT_OF_RANGE: ParseError = ParseError(ParseErrorKind::OutOfRange);
const IMPOSSIBLE: ParseError = ParseError(ParseErrorKind::Impossible);
Expand Down Expand Up @@ -356,7 +367,7 @@ pub fn format<'a, I>(
static LONG_WEEKDAYS: [&'static str; 7] =
["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"];

use std::fmt::Write;
use core::fmt::Write;
let mut result = String::new();

for item in items {
Expand Down
2 changes: 1 addition & 1 deletion src/format/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

#![allow(deprecated)]

use std::usize;
use core::usize;

use Weekday;

Expand Down
15 changes: 13 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,8 @@
#![deny(missing_docs)]
#![deny(missing_debug_implementations)]

#![cfg_attr(not(any(feature = "std", test)), no_std)]

// The explicit 'static lifetimes are still needed for rustc 1.13-16
// backward compatibility, and this appeases clippy. If minimum rustc
// becomes 1.17, should be able to remove this, those 'static lifetimes,
Expand All @@ -403,6 +405,13 @@
trivially_copy_pass_by_ref,
))]

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

#[cfg(feature="clock")]
extern crate time as oldtime;
extern crate num_integer;
Expand Down Expand Up @@ -678,7 +687,7 @@ impl num_traits::FromPrimitive for Weekday {
}
}

use std::fmt;
use core::fmt;

/// An error resulting from reading `Weekday` value with `FromStr`.
#[derive(Clone, PartialEq)]
Expand All @@ -697,7 +706,9 @@ impl fmt::Debug for ParseWeekdayError {
#[cfg(feature = "serde")]
mod weekday_serde {
use super::Weekday;
use std::fmt;
use core::fmt;
#[cfg(not(any(feature = "std", test)))]
use alloc::format;
use serdelib::{ser, de};

impl ser::Serialize for Weekday {
Expand Down
12 changes: 7 additions & 5 deletions src/naive/date.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@

//! ISO 8601 calendar date without timezone.

use std::{str, fmt};
use std::ops::{Add, Sub, AddAssign, SubAssign};
use core::{str, fmt};
use core::ops::{Add, Sub, AddAssign, SubAssign};
use num_traits::ToPrimitive;
use oldtime::Duration as OldDuration;

Expand Down Expand Up @@ -1387,7 +1387,7 @@ impl SubAssign<OldDuration> for NaiveDate {

/// Subtracts another `NaiveDate` from the current date.
/// Returns a `Duration` of integral numbers.
///
///
/// This does not overflow or underflow at all,
/// as all possible output fits in the range of `Duration`.
///
Expand Down Expand Up @@ -1600,7 +1600,9 @@ mod rustc_serialize {

#[cfg(feature = "serde")]
mod serde {
use std::fmt;
use core::fmt;
#[cfg(not(any(feature = "std", test)))]
use alloc::format;
use super::NaiveDate;
use serdelib::{ser, de};

Expand Down Expand Up @@ -1629,7 +1631,7 @@ mod serde {
impl<'de> de::Visitor<'de> for NaiveDateVisitor {
type Value = NaiveDate;

fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result
{
write!(formatter, "a formatted date string")
}
Expand Down
Loading