Skip to content

Commit

Permalink
Split ext into multiple modules internally
Browse files Browse the repository at this point in the history
  • Loading branch information
jhpratt committed Mar 19, 2024
1 parent 5b0c627 commit be2c931
Show file tree
Hide file tree
Showing 4 changed files with 177 additions and 167 deletions.
26 changes: 26 additions & 0 deletions time/src/ext/digit_count.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
use num_conv::prelude::*;

/// A trait that indicates the formatted width of the value can be determined.
///
/// Note that this should not be implemented for any signed integers. This forces the caller to
/// write the sign if desired.
pub(crate) trait DigitCount {
/// The number of digits in the stringified value.
fn num_digits(self) -> u8;
}

/// A macro to generate implementations of `DigitCount` for unsigned integers.
macro_rules! impl_digit_count {
($($t:ty),* $(,)?) => {
$(impl DigitCount for $t {
fn num_digits(self) -> u8 {
match self.checked_ilog10() {
Some(n) => n.truncate::<u8>() + 1,
None => 1,
}
}
})*
};
}

impl_digit_count!(u8, u16, u32);
9 changes: 9 additions & 0 deletions time/src/ext/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
//! Extension traits.
mod digit_count;
mod numerical_duration;
mod numerical_std_duration;

pub(crate) use self::digit_count::DigitCount;
pub use self::numerical_duration::NumericalDuration;
pub use self::numerical_std_duration::NumericalStdDuration;
140 changes: 140 additions & 0 deletions time/src/ext/numerical_duration.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
use crate::convert::*;
use crate::Duration;

/// Sealed trait to prevent downstream implementations.
mod sealed {
/// A trait that cannot be implemented by downstream users.
pub trait Sealed {}
impl Sealed for i64 {}
impl Sealed for f64 {}
}

/// Create [`Duration`]s from numeric literals.
///
/// # Examples
///
/// Basic construction of [`Duration`]s.
///
/// ```rust
/// # use time::{Duration, ext::NumericalDuration};
/// assert_eq!(5.nanoseconds(), Duration::nanoseconds(5));
/// assert_eq!(5.microseconds(), Duration::microseconds(5));
/// assert_eq!(5.milliseconds(), Duration::milliseconds(5));
/// assert_eq!(5.seconds(), Duration::seconds(5));
/// assert_eq!(5.minutes(), Duration::minutes(5));
/// assert_eq!(5.hours(), Duration::hours(5));
/// assert_eq!(5.days(), Duration::days(5));
/// assert_eq!(5.weeks(), Duration::weeks(5));
/// ```
///
/// Signed integers work as well!
///
/// ```rust
/// # use time::{Duration, ext::NumericalDuration};
/// assert_eq!((-5).nanoseconds(), Duration::nanoseconds(-5));
/// assert_eq!((-5).microseconds(), Duration::microseconds(-5));
/// assert_eq!((-5).milliseconds(), Duration::milliseconds(-5));
/// assert_eq!((-5).seconds(), Duration::seconds(-5));
/// assert_eq!((-5).minutes(), Duration::minutes(-5));
/// assert_eq!((-5).hours(), Duration::hours(-5));
/// assert_eq!((-5).days(), Duration::days(-5));
/// assert_eq!((-5).weeks(), Duration::weeks(-5));
/// ```
///
/// Just like any other [`Duration`], they can be added, subtracted, etc.
///
/// ```rust
/// # use time::ext::NumericalDuration;
/// assert_eq!(2.seconds() + 500.milliseconds(), 2_500.milliseconds());
/// assert_eq!(2.seconds() - 500.milliseconds(), 1_500.milliseconds());
/// ```
///
/// When called on floating point values, any remainder of the floating point value will be
/// truncated. Keep in mind that floating point numbers are inherently imprecise and have
/// limited capacity.
pub trait NumericalDuration: sealed::Sealed {
/// Create a [`Duration`] from the number of nanoseconds.
fn nanoseconds(self) -> Duration;
/// Create a [`Duration`] from the number of microseconds.
fn microseconds(self) -> Duration;
/// Create a [`Duration`] from the number of milliseconds.
fn milliseconds(self) -> Duration;
/// Create a [`Duration`] from the number of seconds.
fn seconds(self) -> Duration;
/// Create a [`Duration`] from the number of minutes.
fn minutes(self) -> Duration;
/// Create a [`Duration`] from the number of hours.
fn hours(self) -> Duration;
/// Create a [`Duration`] from the number of days.
fn days(self) -> Duration;
/// Create a [`Duration`] from the number of weeks.
fn weeks(self) -> Duration;
}

impl NumericalDuration for i64 {
fn nanoseconds(self) -> Duration {
Duration::nanoseconds(self)
}

fn microseconds(self) -> Duration {
Duration::microseconds(self)
}

fn milliseconds(self) -> Duration {
Duration::milliseconds(self)
}

fn seconds(self) -> Duration {
Duration::seconds(self)
}

fn minutes(self) -> Duration {
Duration::minutes(self)
}

fn hours(self) -> Duration {
Duration::hours(self)
}

fn days(self) -> Duration {
Duration::days(self)
}

fn weeks(self) -> Duration {
Duration::weeks(self)
}
}

impl NumericalDuration for f64 {
fn nanoseconds(self) -> Duration {
Duration::nanoseconds(self as _)
}

fn microseconds(self) -> Duration {
Duration::nanoseconds((self * Nanosecond::per(Microsecond) as Self) as _)
}

fn milliseconds(self) -> Duration {
Duration::nanoseconds((self * Nanosecond::per(Millisecond) as Self) as _)
}

fn seconds(self) -> Duration {
Duration::nanoseconds((self * Nanosecond::per(Second) as Self) as _)
}

fn minutes(self) -> Duration {
Duration::nanoseconds((self * Nanosecond::per(Minute) as Self) as _)
}

fn hours(self) -> Duration {
Duration::nanoseconds((self * Nanosecond::per(Hour) as Self) as _)
}

fn days(self) -> Duration {
Duration::nanoseconds((self * Nanosecond::per(Day) as Self) as _)
}

fn weeks(self) -> Duration {
Duration::nanoseconds((self * Nanosecond::per(Week) as Self) as _)
}
}
169 changes: 2 additions & 167 deletions time/src/ext.rs → time/src/ext/numerical_std_duration.rs
Original file line number Diff line number Diff line change
@@ -1,154 +1,17 @@
//! Extension traits.
use core::time::Duration as StdDuration;

use num_conv::prelude::*;

use crate::convert::*;
use crate::Duration;

/// Sealed trait to prevent downstream implementations.
mod sealed {
/// A trait that cannot be implemented by downstream users.
pub trait Sealed {}
impl Sealed for i64 {}
impl Sealed for u64 {}
impl Sealed for f64 {}
}

// region: NumericalDuration
/// Create [`Duration`]s from numeric literals.
///
/// # Examples
///
/// Basic construction of [`Duration`]s.
///
/// ```rust
/// # use time::{Duration, ext::NumericalDuration};
/// assert_eq!(5.nanoseconds(), Duration::nanoseconds(5));
/// assert_eq!(5.microseconds(), Duration::microseconds(5));
/// assert_eq!(5.milliseconds(), Duration::milliseconds(5));
/// assert_eq!(5.seconds(), Duration::seconds(5));
/// assert_eq!(5.minutes(), Duration::minutes(5));
/// assert_eq!(5.hours(), Duration::hours(5));
/// assert_eq!(5.days(), Duration::days(5));
/// assert_eq!(5.weeks(), Duration::weeks(5));
/// ```
///
/// Signed integers work as well!
///
/// ```rust
/// # use time::{Duration, ext::NumericalDuration};
/// assert_eq!((-5).nanoseconds(), Duration::nanoseconds(-5));
/// assert_eq!((-5).microseconds(), Duration::microseconds(-5));
/// assert_eq!((-5).milliseconds(), Duration::milliseconds(-5));
/// assert_eq!((-5).seconds(), Duration::seconds(-5));
/// assert_eq!((-5).minutes(), Duration::minutes(-5));
/// assert_eq!((-5).hours(), Duration::hours(-5));
/// assert_eq!((-5).days(), Duration::days(-5));
/// assert_eq!((-5).weeks(), Duration::weeks(-5));
/// ```
///
/// Just like any other [`Duration`], they can be added, subtracted, etc.
///
/// ```rust
/// # use time::ext::NumericalDuration;
/// assert_eq!(2.seconds() + 500.milliseconds(), 2_500.milliseconds());
/// assert_eq!(2.seconds() - 500.milliseconds(), 1_500.milliseconds());
/// ```
///
/// When called on floating point values, any remainder of the floating point value will be
/// truncated. Keep in mind that floating point numbers are inherently imprecise and have limited
/// capacity.
pub trait NumericalDuration: sealed::Sealed {
/// Create a [`Duration`] from the number of nanoseconds.
fn nanoseconds(self) -> Duration;
/// Create a [`Duration`] from the number of microseconds.
fn microseconds(self) -> Duration;
/// Create a [`Duration`] from the number of milliseconds.
fn milliseconds(self) -> Duration;
/// Create a [`Duration`] from the number of seconds.
fn seconds(self) -> Duration;
/// Create a [`Duration`] from the number of minutes.
fn minutes(self) -> Duration;
/// Create a [`Duration`] from the number of hours.
fn hours(self) -> Duration;
/// Create a [`Duration`] from the number of days.
fn days(self) -> Duration;
/// Create a [`Duration`] from the number of weeks.
fn weeks(self) -> Duration;
}

impl NumericalDuration for i64 {
fn nanoseconds(self) -> Duration {
Duration::nanoseconds(self)
}

fn microseconds(self) -> Duration {
Duration::microseconds(self)
}

fn milliseconds(self) -> Duration {
Duration::milliseconds(self)
}

fn seconds(self) -> Duration {
Duration::seconds(self)
}

fn minutes(self) -> Duration {
Duration::minutes(self)
}

fn hours(self) -> Duration {
Duration::hours(self)
}

fn days(self) -> Duration {
Duration::days(self)
}

fn weeks(self) -> Duration {
Duration::weeks(self)
}
}

impl NumericalDuration for f64 {
fn nanoseconds(self) -> Duration {
Duration::nanoseconds(self as _)
}

fn microseconds(self) -> Duration {
Duration::nanoseconds((self * Nanosecond::per(Microsecond) as Self) as _)
}

fn milliseconds(self) -> Duration {
Duration::nanoseconds((self * Nanosecond::per(Millisecond) as Self) as _)
}

fn seconds(self) -> Duration {
Duration::nanoseconds((self * Nanosecond::per(Second) as Self) as _)
}

fn minutes(self) -> Duration {
Duration::nanoseconds((self * Nanosecond::per(Minute) as Self) as _)
}

fn hours(self) -> Duration {
Duration::nanoseconds((self * Nanosecond::per(Hour) as Self) as _)
}

fn days(self) -> Duration {
Duration::nanoseconds((self * Nanosecond::per(Day) as Self) as _)
}

fn weeks(self) -> Duration {
Duration::nanoseconds((self * Nanosecond::per(Week) as Self) as _)
}
}
// endregion NumericalDuration

// region: NumericalStdDuration
/// Create [`std::time::Duration`]s from numeric literals.
///
/// # Examples
Expand Down Expand Up @@ -183,8 +46,8 @@ impl NumericalDuration for f64 {
/// ```
///
/// When called on floating point values, any remainder of the floating point value will be
/// truncated. Keep in mind that floating point numbers are inherently imprecise and have limited
/// capacity.
/// truncated. Keep in mind that floating point numbers are inherently imprecise and have
/// limited capacity.
pub trait NumericalStdDuration: sealed::Sealed {
/// Create a [`std::time::Duration`] from the number of nanoseconds.
fn std_nanoseconds(self) -> StdDuration;
Expand Down Expand Up @@ -327,31 +190,3 @@ impl NumericalStdDuration for f64 {
StdDuration::from_nanos((self * Nanosecond::per(Week) as Self) as _)
}
}
// endregion NumericalStdDuration

// region: DigitCount
/// A trait that indicates the formatted width of the value can be determined.
///
/// Note that this should not be implemented for any signed integers. This forces the caller to
/// write the sign if desired.
pub(crate) trait DigitCount {
/// The number of digits in the stringified value.
fn num_digits(self) -> u8;
}

/// A macro to generate implementations of `DigitCount` for unsigned integers.
macro_rules! impl_digit_count {
($($t:ty),* $(,)?) => {
$(impl DigitCount for $t {
fn num_digits(self) -> u8 {
match self.checked_ilog10() {
Some(n) => n.truncate::<u8>() + 1,
None => 1,
}
}
})*
};
}

impl_digit_count!(u8, u16, u32);
// endregion DigitCount

0 comments on commit be2c931

Please sign in to comment.