Skip to content

Commit fcbadd3

Browse files
committed
Apply feedback and move Finitef64 to primitive.rs
1 parent b4f700c commit fcbadd3

File tree

12 files changed

+171
-178
lines changed

12 files changed

+171
-178
lines changed

src/components/date.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use crate::{
1414
TemporalUnit,
1515
},
1616
parsers::parse_date_time,
17-
utils::FiniteF64,
17+
primitive::FiniteF64,
1818
Sign, TemporalError, TemporalFields, TemporalResult, TemporalUnwrap,
1919
};
2020
use std::str::FromStr;

src/components/datetime.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -531,7 +531,7 @@ mod tests {
531531
components::{calendar::Calendar, duration::DateDuration, Duration},
532532
iso::{IsoDate, IsoTime},
533533
options::{DifferenceSettings, RoundingIncrement, TemporalRoundingMode, TemporalUnit},
534-
utils::FiniteF64,
534+
primitive::FiniteF64,
535535
};
536536

537537
use super::DateTime;

src/components/duration.rs

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,8 @@ use crate::{
44
components::{DateTime, Time},
55
iso::{IsoDateTime, IsoTime},
66
options::{RelativeTo, ResolvedRoundingOptions, RoundingOptions, TemporalUnit},
7-
temporal_assert,
8-
utils::FiniteF64,
9-
Sign, TemporalError, TemporalResult,
7+
primitive::FiniteF64,
8+
temporal_assert, Sign, TemporalError, TemporalResult,
109
};
1110
use ixdtf::parsers::{records::TimeDurationRecord, IsoDurationParser};
1211
use num_traits::AsPrimitive;
@@ -795,16 +794,16 @@ impl FromStr for Duration {
795794
let sign = f64::from(parse_record.sign as i8);
796795

797796
Self::new(
798-
FiniteF64::from(years).unchecked_mul(sign),
799-
FiniteF64::from(months).unchecked_mul(sign),
800-
FiniteF64::from(weeks).unchecked_mul(sign),
801-
FiniteF64::from(days).unchecked_mul(sign),
802-
FiniteF64::try_from(hours)?.unchecked_mul(sign),
803-
FiniteF64::try_from(minutes)?.unchecked_mul(sign),
804-
FiniteF64::try_from(seconds)?.unchecked_mul(sign),
805-
FiniteF64::try_from(millis)?.unchecked_mul(sign),
806-
FiniteF64::try_from(micros)?.unchecked_mul(sign),
807-
FiniteF64::try_from(nanos)?.unchecked_mul(sign),
797+
FiniteF64::from(years).copysign(sign),
798+
FiniteF64::from(months).copysign(sign),
799+
FiniteF64::from(weeks).copysign(sign),
800+
FiniteF64::from(days).copysign(sign),
801+
FiniteF64::try_from(hours)?.copysign(sign),
802+
FiniteF64::try_from(minutes)?.copysign(sign),
803+
FiniteF64::try_from(seconds)?.copysign(sign),
804+
FiniteF64::try_from(millis)?.copysign(sign),
805+
FiniteF64::try_from(micros)?.copysign(sign),
806+
FiniteF64::try_from(nanos)?.copysign(sign),
808807
)
809808
}
810809
}

src/components/duration/date.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! Implementation of a `DateDuration`
22
3-
use crate::{utils::FiniteF64, Sign, TemporalError, TemporalResult};
3+
use crate::{primitive::FiniteF64, Sign, TemporalError, TemporalResult};
44

55
/// `DateDuration` represents the [date duration record][spec] of the `Duration.`
66
///

src/components/duration/normalized.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ use crate::{
88
components::{tz::TimeZone, Date, DateTime},
99
iso::IsoDate,
1010
options::{ArithmeticOverflow, ResolvedRoundingOptions, TemporalRoundingMode, TemporalUnit},
11+
primitive::FiniteF64,
1112
rounding::{IncrementRounder, Round},
12-
utils::FiniteF64,
1313
TemporalError, TemporalResult, TemporalUnwrap, NS_PER_DAY,
1414
};
1515

src/components/duration/time.rs

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,9 @@ use std::num::NonZeroU128;
44

55
use crate::{
66
options::{ResolvedRoundingOptions, TemporalUnit},
7+
primitive::FiniteF64,
78
rounding::{IncrementRounder, Round},
8-
temporal_assert,
9-
utils::FiniteF64,
10-
TemporalError, TemporalResult, TemporalUnwrap,
9+
temporal_assert, TemporalError, TemporalResult, TemporalUnwrap,
1110
};
1211

1312
use super::{
@@ -16,7 +15,7 @@ use super::{
1615
DateDuration,
1716
};
1817

19-
use num_traits::{Euclid, FromPrimitive, MulAdd};
18+
use num_traits::{Euclid, FromPrimitive};
2019

2120
/// `TimeDuration` represents the [Time Duration record][spec] of the `Duration.`
2221
///
@@ -198,17 +197,16 @@ impl TimeDuration {
198197

199198
// NOTE: days may have the potentially to exceed i64
200199
// 12. Return ! CreateTimeDurationRecord(days × sign, hours × sign, minutes × sign, seconds × sign, milliseconds × sign, microseconds × sign, nanoseconds × sign).
201-
let days = (days as i64).mul_add(sign.into(), 0);
200+
let days = FiniteF64::try_from(days as f64)?.copysign(sign.into());
202201
let result = Self::new_unchecked(
203-
FiniteF64::from((hours as i32).mul_add(sign, 0)),
204-
FiniteF64::from((minutes as i32).mul_add(sign, 0)),
205-
FiniteF64::from((seconds as i32).mul_add(sign, 0)),
206-
FiniteF64::from((milliseconds as i32).mul_add(sign, 0)),
207-
FiniteF64::from((microseconds as i32).mul_add(sign, 0)),
208-
FiniteF64::from((nanoseconds as i32).mul_add(sign, 0)),
202+
FiniteF64::try_from(hours)?.copysign(f64::from(sign)),
203+
FiniteF64::try_from(minutes)?.copysign(f64::from(sign)),
204+
FiniteF64::try_from(seconds)?.copysign(f64::from(sign)),
205+
FiniteF64::try_from(milliseconds)?.copysign(f64::from(sign)),
206+
FiniteF64::try_from(microseconds)?.copysign(f64::from(sign)),
207+
FiniteF64::try_from(nanoseconds)?.copysign(f64::from(sign)),
209208
);
210209

211-
let days = FiniteF64::try_from(days as f64)?;
212210
if !is_valid_duration(
213211
FiniteF64::default(),
214212
FiniteF64::default(),

src/components/instant.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ use crate::{
1010
RoundingOptions, TemporalUnit,
1111
},
1212
parsers::parse_instant,
13+
primitive::FiniteF64,
1314
rounding::{IncrementRounder, Round},
14-
utils::FiniteF64,
1515
Sign, TemporalError, TemporalResult, TemporalUnwrap,
1616
};
1717

@@ -321,7 +321,7 @@ mod tests {
321321
use crate::{
322322
components::{duration::TimeDuration, Instant},
323323
options::{DifferenceSettings, TemporalRoundingMode, TemporalUnit},
324-
utils::FiniteF64,
324+
primitive::FiniteF64,
325325
NS_MAX_INSTANT, NS_MIN_INSTANT,
326326
};
327327
use num_traits::ToPrimitive;

src/components/time.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use crate::{
88
RoundingIncrement, TemporalRoundingMode, TemporalUnit,
99
},
1010
parsers::parse_time,
11-
utils::FiniteF64,
11+
primitive::FiniteF64,
1212
Sign, TemporalError, TemporalResult,
1313
};
1414

src/iso.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,9 @@ use crate::{
2525
},
2626
error::TemporalError,
2727
options::{ArithmeticOverflow, RoundingIncrement, TemporalRoundingMode, TemporalUnit},
28+
primitive::FiniteF64,
2829
rounding::{IncrementRounder, Round},
29-
temporal_assert,
30-
utils::{self, FiniteF64},
31-
TemporalResult, TemporalUnwrap, NS_PER_DAY,
30+
temporal_assert, utils, TemporalResult, TemporalUnwrap, NS_PER_DAY,
3231
};
3332
use icu_calendar::{Date as IcuDate, Iso};
3433
use num_bigint::BigInt;

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ pub mod fields;
4444
pub mod iso;
4545
pub mod options;
4646
pub mod parsers;
47+
pub mod primitive;
4748

4849
#[doc(hidden)]
4950
pub(crate) mod rounding;

src/primitive.rs

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
//! Implementation of the FiniteF64 primitive
2+
3+
use crate::{TemporalError, TemporalResult};
4+
use num_traits::{AsPrimitive, FromPrimitive};
5+
6+
#[derive(Debug, Default, Clone, Copy, PartialEq, PartialOrd)]
7+
pub struct FiniteF64(pub(crate) f64);
8+
9+
impl FiniteF64 {
10+
#[inline]
11+
pub fn as_inner(&self) -> f64 {
12+
self.0
13+
}
14+
15+
#[inline]
16+
pub fn is_zero(&self) -> bool {
17+
self.0 == 0.0
18+
}
19+
20+
#[inline]
21+
pub fn negate(&self) -> Self {
22+
if !self.is_zero() {
23+
Self(self.0 * -1.0)
24+
} else {
25+
*self
26+
}
27+
}
28+
29+
#[inline]
30+
pub fn abs(&self) -> Self {
31+
Self(self.0.abs())
32+
}
33+
34+
#[inline]
35+
pub fn checked_add(&self, other: &Self) -> TemporalResult<Self> {
36+
let result = Self(self.0 + other.0);
37+
if !result.0.is_finite() {
38+
return Err(TemporalError::range().with_message("number value is not a finite value."));
39+
}
40+
Ok(result)
41+
}
42+
43+
#[inline]
44+
pub fn checked_mul_add(&self, a: FiniteF64, b: FiniteF64) -> TemporalResult<Self> {
45+
let result = Self(self.0.mul_add(a.0, b.0));
46+
if !result.0.is_finite() {
47+
return Err(TemporalError::range().with_message("number value is not a finite value."));
48+
}
49+
Ok(result)
50+
}
51+
52+
pub fn copysign(&self, other: f64) -> Self {
53+
Self(self.0.copysign(other))
54+
}
55+
56+
pub(crate) fn as_date_value(&self) -> TemporalResult<i32> {
57+
if !(f64::from(i32::MIN)..=f64::from(i32::MAX)).contains(&self.0) {
58+
return Err(TemporalError::range().with_message("number exceeds a valid date value."));
59+
}
60+
Ok(self.0 as i32)
61+
}
62+
}
63+
64+
impl AsPrimitive<i64> for FiniteF64 {
65+
fn as_(self) -> i64 {
66+
self.0 as i64
67+
}
68+
}
69+
70+
impl AsPrimitive<i128> for FiniteF64 {
71+
fn as_(self) -> i128 {
72+
self.0 as i128
73+
}
74+
}
75+
76+
impl TryFrom<f64> for FiniteF64 {
77+
type Error = TemporalError;
78+
fn try_from(value: f64) -> Result<Self, Self::Error> {
79+
if !value.is_finite() {
80+
return Err(TemporalError::range().with_message("number value is not a finite value."));
81+
}
82+
Ok(Self(value))
83+
}
84+
}
85+
86+
impl TryFrom<i128> for FiniteF64 {
87+
type Error = TemporalError;
88+
fn try_from(value: i128) -> Result<Self, Self::Error> {
89+
let result = f64::from_i128(value)
90+
.ok_or(TemporalError::range().with_message("days exceeded a valid range."))?;
91+
if !result.is_finite() {
92+
return Err(TemporalError::range().with_message("number value is not a finite value."));
93+
}
94+
Ok(Self(result))
95+
}
96+
}
97+
98+
impl From<i8> for FiniteF64 {
99+
fn from(value: i8) -> Self {
100+
Self(f64::from(value))
101+
}
102+
}
103+
104+
impl From<i32> for FiniteF64 {
105+
fn from(value: i32) -> Self {
106+
Self(f64::from(value))
107+
}
108+
}
109+
110+
impl From<u8> for FiniteF64 {
111+
fn from(value: u8) -> Self {
112+
Self(f64::from(value))
113+
}
114+
}
115+
116+
impl From<u16> for FiniteF64 {
117+
fn from(value: u16) -> Self {
118+
Self(f64::from(value))
119+
}
120+
}
121+
122+
impl From<u32> for FiniteF64 {
123+
fn from(value: u32) -> Self {
124+
Self(f64::from(value))
125+
}
126+
}
127+
128+
impl PartialEq<f64> for FiniteF64 {
129+
fn eq(&self, other: &f64) -> bool {
130+
self.0 == *other
131+
}
132+
}
133+
134+
impl PartialOrd<f64> for FiniteF64 {
135+
fn partial_cmp(&self, other: &f64) -> Option<std::cmp::Ordering> {
136+
self.0.partial_cmp(other)
137+
}
138+
}

0 commit comments

Comments
 (0)