Skip to content

Commit

Permalink
Inline a handful of functions from num-integer
Browse files Browse the repository at this point in the history
The motivation for this is that we use a very small portion of what num-integer provides, but it's a relatively heavy dependency -- it brings in several crates with build scripts. The goal here is to reduce compilation time for projects using chrono.
  • Loading branch information
alex committed Mar 30, 2023
1 parent 2fcdd9e commit 531316a
Show file tree
Hide file tree
Showing 10 changed files with 93 additions and 10 deletions.
1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ __internal_bench = ["criterion"]
__doctest = []

[dependencies]
num-integer = { version = "0.1.36", default-features = false }
serde = { version = "1.0.99", default-features = false, optional = true }
pure-rust-locales = { version = "0.5.2", optional = true }
criterion = { version = "0.4.0", optional = true }
Expand Down
2 changes: 1 addition & 1 deletion src/format/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -506,7 +506,7 @@ fn format_inner(
) -> fmt::Result {
let locale = Locales::new(locale);

use num_integer::{div_floor, mod_floor};
use crate::utils::{div_floor, mod_floor};

match *item {
Item::Literal(s) | Item::Space(s) => result.push_str(s),
Expand Down
3 changes: 1 addition & 2 deletions src/format/parsed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,10 @@
use core::convert::TryFrom;

use num_integer::div_rem;

use super::{ParseResult, IMPOSSIBLE, NOT_ENOUGH, OUT_OF_RANGE};
use crate::naive::{NaiveDate, NaiveDateTime, NaiveTime};
use crate::offset::{FixedOffset, LocalResult, Offset, TimeZone};
use crate::utils::div_rem;
use crate::{DateTime, Datelike, TimeDelta, Timelike, Weekday};

/// Parsed parts of date and time. There are two classes of methods:
Expand Down
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,8 @@ pub use traits::{Datelike, Timelike};
#[doc(hidden)]
pub use naive::__BenchYearFlags;

mod utils;

/// Serialization/Deserialization with serde.
///
/// This module provides default implementations for `DateTime` using the [RFC 3339][1] format and various
Expand Down
2 changes: 1 addition & 1 deletion src/naive/date.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ use core::convert::TryFrom;
use core::ops::{Add, AddAssign, RangeInclusive, Sub, SubAssign};
use core::{fmt, str};

use num_integer::div_mod_floor;
#[cfg(feature = "rkyv")]
use rkyv::{Archive, Deserialize, Serialize};

Expand All @@ -23,6 +22,7 @@ use crate::format::{parse, write_hundreds, ParseError, ParseResult, Parsed, Strf
use crate::format::{Item, Numeric, Pad};
use crate::month::Months;
use crate::naive::{IsoWeek, NaiveDateTime, NaiveTime};
use crate::utils::div_mod_floor;
use crate::{Datelike, TimeDelta, Weekday};

use super::internals::{self, DateImpl, Mdf, Of, YearFlags};
Expand Down
2 changes: 1 addition & 1 deletion src/naive/datetime/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ use core::fmt::Write;
use core::ops::{Add, AddAssign, Sub, SubAssign};
use core::{fmt, str};

use num_integer::div_mod_floor;
#[cfg(feature = "rkyv")]
use rkyv::{Archive, Deserialize, Serialize};

Expand All @@ -20,6 +19,7 @@ use crate::format::DelayedFormat;
use crate::format::{parse, ParseError, ParseResult, Parsed, StrftimeItems};
use crate::format::{Fixed, Item, Numeric, Pad};
use crate::naive::{Days, IsoWeek, NaiveDate, NaiveTime};
use crate::utils::div_mod_floor;
use crate::{DateTime, Datelike, LocalResult, Months, TimeDelta, TimeZone, Timelike, Weekday};

/// Tools to help serializing/deserializing `NaiveDateTime`s
Expand Down
3 changes: 1 addition & 2 deletions src/naive/internals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@
use core::convert::TryFrom;
use core::{fmt, i32};

use num_integer::{div_rem, mod_floor};

use crate::utils::{div_rem, mod_floor};
use crate::Weekday;

/// The internal date representation. This also includes the packed `Mdf` value.
Expand Down
2 changes: 1 addition & 1 deletion src/naive/time/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ use core::borrow::Borrow;
use core::ops::{Add, AddAssign, Sub, SubAssign};
use core::{fmt, str};

use num_integer::div_mod_floor;
#[cfg(feature = "rkyv")]
use rkyv::{Archive, Deserialize, Serialize};

#[cfg(any(feature = "alloc", feature = "std", test))]
use crate::format::DelayedFormat;
use crate::format::{parse, write_hundreds, ParseError, ParseResult, Parsed, StrftimeItems};
use crate::format::{Fixed, Item, Numeric, Pad};
use crate::utils::div_mod_floor;
use crate::{TimeDelta, Timelike};

#[cfg(feature = "serde")]
Expand Down
2 changes: 1 addition & 1 deletion src/offset/fixed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@
use core::fmt;
use core::ops::{Add, Sub};

use num_integer::div_mod_floor;
#[cfg(feature = "rkyv")]
use rkyv::{Archive, Deserialize, Serialize};

use super::{LocalResult, Offset, TimeZone};
use crate::naive::{NaiveDate, NaiveDateTime, NaiveTime};
use crate::time_delta::TimeDelta;
use crate::utils::div_mod_floor;
use crate::DateTime;
use crate::Timelike;

Expand Down
84 changes: 84 additions & 0 deletions src/utils.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// All code cribbed from num-integer. We do this to minimize dependencies and
// build-time.

pub(crate) trait Integer: Copy {
fn div_rem(self, other: Self) -> (Self, Self);
fn div_floor(self, other: Self) -> Self;
fn mod_floor(self, other: Self) -> Self;
}

macro_rules! impl_integer_signed {
($t: ty) => {
impl Integer for $t {
#[inline]
fn div_rem(self, other: Self) -> (Self, Self) {
(self / other, self % other)
}

#[inline]
fn div_floor(self, other: Self) -> Self {
// Algorithm from [Daan Leijen. _Division and Modulus for Computer Scientists_,
// December 2001](http://research.microsoft.com/pubs/151917/divmodnote-letter.pdf)
let (d, r) = self.div_rem(other);
if (r > 0 && other < 0) || (r < 0 && other > 0) {
d - 1
} else {
d
}
}

#[inline]
fn mod_floor(self, other: Self) -> Self {
// Algorithm from [Daan Leijen. _Division and Modulus for Computer Scientists_,
// December 2001](http://research.microsoft.com/pubs/151917/divmodnote-letter.pdf)
let r = self % other;
if (r > 0 && other < 0) || (r < 0 && other > 0) {
r + other
} else {
r
}
}
}
};
}

macro_rules! impl_integer_unsigned {
($t: ty) => {
impl Integer for $t {
#[inline]
fn div_rem(self, other: Self) -> (Self, Self) {
(self / other, self % other)
}

#[inline]
fn div_floor(self, other: Self) -> Self {
self / other
}

#[inline]
fn mod_floor(self, other: Self) -> Self {
self % other
}
}
};
}

impl_integer_signed!(i32);
impl_integer_signed!(i64);
impl_integer_unsigned!(u32);

pub(crate) fn div_mod_floor<T: Integer>(x: T, y: T) -> (T, T) {
(div_floor(x, y), mod_floor(x, y))
}

pub(crate) fn div_rem<T: Integer>(x: T, y: T) -> (T, T) {
x.div_rem(y)
}

pub(crate) fn div_floor<T: Integer>(x: T, y: T) -> T {
x.div_floor(y)
}

pub(crate) fn mod_floor<T: Integer>(x: T, y: T) -> T {
x.mod_floor(y)
}

0 comments on commit 531316a

Please sign in to comment.