Skip to content

Commit

Permalink
Reduce number of as conversions
Browse files Browse the repository at this point in the history
Use the new `num-conv` crate where possible. Current limitations are the
inability to work in `const` contexts and the lack of support for
platform-dependent `usize` and `isize`.
  • Loading branch information
jhpratt committed Dec 24, 2023
1 parent 490626b commit c9ec426
Show file tree
Hide file tree
Showing 24 changed files with 212 additions and 150 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Expand Up @@ -14,6 +14,7 @@ deranged = { version = "0.3.9", default-features = false, features = [
itoa = "1.0.1"
js-sys = "0.3.58"
libc = "0.2.98"
num-conv = "0.1.0"
num_threads = "0.1.2"
powerfmt = { version = "0.2.0", default-features = false }
quickcheck = { version = "1.0.3", default-features = false }
Expand Down
20 changes: 7 additions & 13 deletions tests/compile-fail/invalid_offset.stderr
@@ -1,49 +1,43 @@
error: invalid component: hour was 24
--> $DIR/invalid_offset.rs:4:22
|
4 | let _ = offset!(+24);
| ^^

error: invalid component: minute was 60
--> $DIR/invalid_offset.rs:5:24
--> ../tests/compile-fail/invalid_offset.rs:5:24
|
5 | let _ = offset!(+0:60);
| ^^

error: invalid component: second was 60
--> $DIR/invalid_offset.rs:6:27
--> ../tests/compile-fail/invalid_offset.rs:6:27
|
6 | let _ = offset!(+0:00:60);
| ^^

error: unexpected token: 0
--> $DIR/invalid_offset.rs:7:21
--> ../tests/compile-fail/invalid_offset.rs:7:21
|
7 | let _ = offset!(0);
| ^

error: missing component: sign
--> $DIR/invalid_offset.rs:8:13
--> ../tests/compile-fail/invalid_offset.rs:8:13
|
8 | let _ = offset!();
| ^^^^^^^^^
|
= note: this error originates in the macro `offset` (in Nightly builds, run with -Z macro-backtrace for more info)

error: invalid component: hour was 0a
--> $DIR/invalid_offset.rs:9:22
--> ../tests/compile-fail/invalid_offset.rs:9:22
|
9 | let _ = offset!(+0a);
| ^^

error: invalid component: minute was 0a
--> $DIR/invalid_offset.rs:10:24
--> ../tests/compile-fail/invalid_offset.rs:10:24
|
10 | let _ = offset!(+0:0a);
| ^^

error: invalid component: second was 0a
--> $DIR/invalid_offset.rs:11:27
--> ../tests/compile-fail/invalid_offset.rs:11:27
|
11 | let _ = offset!(+0:00:0a);
| ^^
1 change: 1 addition & 0 deletions time-macros/Cargo.toml
Expand Up @@ -30,3 +30,4 @@ workspace = true

[dependencies]
time-core = { workspace = true }
num-conv = { workspace = true }
3 changes: 2 additions & 1 deletion time-macros/src/date.rs
@@ -1,5 +1,6 @@
use std::iter::Peekable;

use num_conv::Truncate;
use proc_macro::{token_stream, TokenTree};
use time_core::util::{days_in_year, weeks_in_year};

Expand Down Expand Up @@ -93,7 +94,7 @@ pub(crate) fn parse(chars: &mut Peekable<token_stream::IntoIter>) -> Result<Date
span_end: Some(month_span),
});
}
let month = month as _;
let month = month.truncate();
if day == 0 || day > days_in_year_month(year, month) {
return Err(Error::InvalidComponent {
name: "day",
Expand Down
16 changes: 10 additions & 6 deletions time-macros/src/helpers/mod.rs
Expand Up @@ -4,6 +4,7 @@ mod string;
use std::iter::Peekable;
use std::str::FromStr;

use num_conv::prelude::*;
use proc_macro::{token_stream, Span, TokenTree};
use time_core::util::{days_in_year, is_leap_year};

Expand Down Expand Up @@ -92,15 +93,17 @@ fn jan_weekday(year: i32, ordinal: i32) -> u8 {
}

let adj_year = year - 1;
((ordinal + adj_year + div_floor!(adj_year, 4) - div_floor!(adj_year, 100)
(ordinal + adj_year + div_floor!(adj_year, 4) - div_floor!(adj_year, 100)
+ div_floor!(adj_year, 400)
+ 6)
.rem_euclid(7)) as _
.rem_euclid(7)
.cast_unsigned()
.truncate()
}

pub(crate) fn days_in_year_month(year: i32, month: u8) -> u8 {
[31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month as usize - 1]
+ (month == 2 && is_leap_year(year)) as u8
[31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month.extend::<usize>() - 1]
+ u8::from(month == 2 && is_leap_year(year))
}

pub(crate) fn ywd_to_yo(year: i32, week: u8, iso_weekday_number: u8) -> (i32, u16) {
Expand All @@ -120,8 +123,9 @@ pub(crate) fn ywd_to_yo(year: i32, week: u8, iso_weekday_number: u8) -> (i32, u1
}

pub(crate) fn ymd_to_yo(year: i32, month: u8, day: u8) -> (i32, u16) {
let ordinal = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334][month as usize - 1]
+ (month > 2 && is_leap_year(year)) as u16;
let ordinal = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334]
[month.extend::<usize>() - 1]
+ u16::from(month > 2 && is_leap_year(year));

(year, ordinal + u16::from(day))
}
5 changes: 3 additions & 2 deletions time-macros/src/offset.rs
@@ -1,5 +1,6 @@
use std::iter::Peekable;

use num_conv::prelude::*;
use proc_macro::{token_stream, Span, TokenTree};
use time_core::convert::*;

Expand Down Expand Up @@ -59,14 +60,14 @@ pub(crate) fn parse(chars: &mut Peekable<token_stream::IntoIter>) -> Result<Offs
span_start: Some(hours_span),
span_end: Some(hours_span),
})
} else if minutes >= Minute::per(Hour) as _ {
} else if minutes >= Minute::per(Hour).cast_signed() {
Err(Error::InvalidComponent {
name: "minute",
value: minutes.to_string(),
span_start: Some(minutes_span),
span_end: Some(minutes_span),
})
} else if seconds >= Second::per(Minute) as _ {
} else if seconds >= Second::per(Minute).cast_signed() {
Err(Error::InvalidComponent {
name: "second",
value: seconds.to_string(),
Expand Down
1 change: 1 addition & 0 deletions time/Cargo.toml
Expand Up @@ -51,6 +51,7 @@ wasm-bindgen = ["dep:js-sys"]
[dependencies]
deranged = { workspace = true }
itoa = { workspace = true, optional = true }
num-conv = { workspace = true }
powerfmt = { workspace = true }
quickcheck = { workspace = true, optional = true }
rand = { workspace = true, optional = true }
Expand Down
11 changes: 6 additions & 5 deletions time/src/date.rs
Expand Up @@ -8,6 +8,7 @@ use core::{cmp, fmt};
use std::io;

use deranged::RangedI32;
use num_conv::prelude::*;
use powerfmt::ext::FormatterExt;
use powerfmt::smart_display::{self, FormatterOptions, Metadata, SmartDisplay};

Expand Down Expand Up @@ -1337,10 +1338,10 @@ impl SmartDisplay for Date {
false
};

let formatted_width = year_width as usize
let formatted_width = year_width.extend::<usize>()
+ smart_display::padded_width_of!(
"-",
month as u8 => width(2),
u8::from(month) => width(2),
"-",
day => width(2),
);
Expand All @@ -1352,7 +1353,7 @@ impl SmartDisplay for Date {
year_width,
display_sign,
year,
month: month as u8,
month: u8::from(month),
day,
},
)
Expand All @@ -1370,7 +1371,7 @@ impl SmartDisplay for Date {
month,
day,
} = *metadata;
let year_width = year_width as usize;
let year_width = year_width.extend();

if display_sign {
f.pad_with_width(
Expand Down Expand Up @@ -1456,7 +1457,7 @@ impl Sub for Date {
type Output = Duration;

fn sub(self, other: Self) -> Self::Output {
Duration::days((self.to_julian_day() - other.to_julian_day()) as _)
Duration::days((self.to_julian_day() - other.to_julian_day()).extend())
}
}
// endregion trait impls
8 changes: 5 additions & 3 deletions time/src/date_time/mod.rs
Expand Up @@ -18,6 +18,7 @@ use std::io;
use std::time::SystemTime;

use deranged::RangedI64;
use num_conv::prelude::*;
use powerfmt::ext::FormatterExt;
use powerfmt::smart_display::{self, FormatterOptions, Metadata, SmartDisplay};

Expand Down Expand Up @@ -948,7 +949,7 @@ impl<T: MaybeTz> Sub<Self> for DateTime<T> {
) {
(Some(self_offset), Some(rhs_offset)) => {
let adjustment = Duration::seconds(
(self_offset.whole_seconds() - rhs_offset.whole_seconds()) as i64,
(self_offset.whole_seconds() - rhs_offset.whole_seconds()).extend::<i64>(),
);
base - adjustment
}
Expand Down Expand Up @@ -1091,8 +1092,9 @@ impl From<js_sys::Date> for DateTime<offset_kind::Fixed> {
impl From<DateTime<offset_kind::Fixed>> for js_sys::Date {
fn from(datetime: DateTime<offset_kind::Fixed>) -> Self {
// new Date() takes milliseconds
let timestamp =
(datetime.unix_timestamp_nanos() / Nanosecond::per(Millisecond) as i128) as f64;
let timestamp = (datetime.unix_timestamp_nanos()
/ Nanosecond::per(Millisecond).cast_signed().extend::<i128>())
as f64;
js_sys::Date::new(&timestamp.into())
}
}
Expand Down
36 changes: 23 additions & 13 deletions time/src/duration.rs
Expand Up @@ -7,6 +7,7 @@ use core::ops::{Add, AddAssign, Div, Mul, Neg, Sub, SubAssign};
use core::time::Duration as StdDuration;

use deranged::RangedI32;
use num_conv::prelude::*;

use crate::convert::*;
use crate::error;
Expand Down Expand Up @@ -1225,23 +1226,26 @@ impl fmt::Display for Duration {
let seconds = self.seconds.unsigned_abs();
let nanoseconds = self.nanoseconds.get().unsigned_abs();

item!("d", seconds / Second::per(Day) as u64)?;
item!("d", seconds / Second::per(Day).extend::<u64>())?;
item!(
"h",
seconds / Second::per(Hour) as u64 % Hour::per(Day) as u64
seconds / Second::per(Hour).extend::<u64>() % Hour::per(Day).extend::<u64>()
)?;
item!(
"m",
seconds / Second::per(Minute) as u64 % Minute::per(Hour) as u64
seconds / Second::per(Minute).extend::<u64>() % Minute::per(Hour).extend::<u64>()
)?;
item!("s", seconds % Second::per(Minute) as u64)?;
item!("s", seconds % Second::per(Minute).extend::<u64>())?;
item!("ms", nanoseconds / Nanosecond::per(Millisecond))?;
item!(
"µs",
nanoseconds / Nanosecond::per(Microsecond) as u32
% Microsecond::per(Millisecond) as u32
nanoseconds / Nanosecond::per(Microsecond).extend::<u32>()
% Microsecond::per(Millisecond).extend::<u32>()
)?;
item!(
"ns",
nanoseconds % Nanosecond::per(Microsecond).extend::<u32>()
)?;
item!("ns", nanoseconds % Nanosecond::per(Microsecond) as u32)?;
}

Ok(())
Expand All @@ -1257,7 +1261,7 @@ impl TryFrom<StdDuration> for Duration {
.as_secs()
.try_into()
.map_err(|_| error::ConversionRange)?,
original.subsec_nanos() as _,
original.subsec_nanos().cast_signed(),
))
}
}
Expand Down Expand Up @@ -1394,7 +1398,7 @@ macro_rules! duration_mul_div_int {
fn mul(self, rhs: $type) -> Self::Output {
Self::nanoseconds_i128(
self.whole_nanoseconds()
.checked_mul(rhs as _)
.checked_mul(rhs.cast_signed().extend::<i128>())
.expect("overflow when multiplying duration")
)
}
Expand All @@ -1412,7 +1416,9 @@ macro_rules! duration_mul_div_int {
type Output = Self;

fn div(self, rhs: $type) -> Self::Output {
Self::nanoseconds_i128(self.whole_nanoseconds() / rhs as i128)
Self::nanoseconds_i128(
self.whole_nanoseconds() / rhs.cast_signed().extend::<i128>()
)
}
}
)+};
Expand Down Expand Up @@ -1509,14 +1515,18 @@ impl PartialEq<Duration> for StdDuration {

impl PartialOrd<StdDuration> for Duration {
fn partial_cmp(&self, rhs: &StdDuration) -> Option<Ordering> {
if rhs.as_secs() > i64::MAX as _ {
if rhs.as_secs() > i64::MAX.cast_unsigned() {
return Some(Ordering::Less);
}

Some(
self.seconds
.cmp(&(rhs.as_secs() as _))
.then_with(|| self.nanoseconds.get().cmp(&(rhs.subsec_nanos() as _))),
.cmp(&rhs.as_secs().cast_signed())
.then_with(|| {
self.nanoseconds
.get()
.cmp(&rhs.subsec_nanos().cast_signed())
}),
)
}
}
Expand Down
12 changes: 7 additions & 5 deletions time/src/ext.rs
Expand Up @@ -2,6 +2,8 @@

use core::time::Duration as StdDuration;

use num_conv::prelude::*;

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

Expand Down Expand Up @@ -224,7 +226,7 @@ impl NumericalStdDuration for u64 {
/// This may panic if an overflow occurs.
fn std_minutes(self) -> StdDuration {
StdDuration::from_secs(
self.checked_mul(Second::per(Minute) as Self)
self.checked_mul(Second::per(Minute).extend())
.expect("overflow constructing `time::Duration`"),
)
}
Expand All @@ -234,7 +236,7 @@ impl NumericalStdDuration for u64 {
/// This may panic if an overflow occurs.
fn std_hours(self) -> StdDuration {
StdDuration::from_secs(
self.checked_mul(Second::per(Hour) as Self)
self.checked_mul(Second::per(Hour).extend())
.expect("overflow constructing `time::Duration`"),
)
}
Expand All @@ -244,7 +246,7 @@ impl NumericalStdDuration for u64 {
/// This may panic if an overflow occurs.
fn std_days(self) -> StdDuration {
StdDuration::from_secs(
self.checked_mul(Second::per(Day) as Self)
self.checked_mul(Second::per(Day).extend())
.expect("overflow constructing `time::Duration`"),
)
}
Expand All @@ -254,7 +256,7 @@ impl NumericalStdDuration for u64 {
/// This may panic if an overflow occurs.
fn std_weeks(self) -> StdDuration {
StdDuration::from_secs(
self.checked_mul(Second::per(Week) as Self)
self.checked_mul(Second::per(Week).extend())
.expect("overflow constructing `time::Duration`"),
)
}
Expand Down Expand Up @@ -343,7 +345,7 @@ macro_rules! impl_digit_count {
$(impl DigitCount for $t {
fn num_digits(self) -> u8 {
match self.checked_ilog10() {
Some(n) => (n as u8) + 1,
Some(n) => n.truncate::<u8>() + 1,
None => 1,
}
}
Expand Down

0 comments on commit c9ec426

Please sign in to comment.