Skip to content

Commit

Permalink
Apply feedback and move Finitef64 to primitive.rs
Browse files Browse the repository at this point in the history
  • Loading branch information
nekevss committed Jul 20, 2024
1 parent b4f700c commit fcbadd3
Show file tree
Hide file tree
Showing 12 changed files with 171 additions and 178 deletions.
2 changes: 1 addition & 1 deletion src/components/date.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use crate::{
TemporalUnit,
},
parsers::parse_date_time,
utils::FiniteF64,
primitive::FiniteF64,
Sign, TemporalError, TemporalFields, TemporalResult, TemporalUnwrap,
};
use std::str::FromStr;
Expand Down
2 changes: 1 addition & 1 deletion src/components/datetime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -531,7 +531,7 @@ mod tests {
components::{calendar::Calendar, duration::DateDuration, Duration},
iso::{IsoDate, IsoTime},
options::{DifferenceSettings, RoundingIncrement, TemporalRoundingMode, TemporalUnit},
utils::FiniteF64,
primitive::FiniteF64,
};

use super::DateTime;
Expand Down
25 changes: 12 additions & 13 deletions src/components/duration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@ use crate::{
components::{DateTime, Time},
iso::{IsoDateTime, IsoTime},
options::{RelativeTo, ResolvedRoundingOptions, RoundingOptions, TemporalUnit},
temporal_assert,
utils::FiniteF64,
Sign, TemporalError, TemporalResult,
primitive::FiniteF64,
temporal_assert, Sign, TemporalError, TemporalResult,
};
use ixdtf::parsers::{records::TimeDurationRecord, IsoDurationParser};
use num_traits::AsPrimitive;
Expand Down Expand Up @@ -795,16 +794,16 @@ impl FromStr for Duration {
let sign = f64::from(parse_record.sign as i8);

Self::new(
FiniteF64::from(years).unchecked_mul(sign),
FiniteF64::from(months).unchecked_mul(sign),
FiniteF64::from(weeks).unchecked_mul(sign),
FiniteF64::from(days).unchecked_mul(sign),
FiniteF64::try_from(hours)?.unchecked_mul(sign),
FiniteF64::try_from(minutes)?.unchecked_mul(sign),
FiniteF64::try_from(seconds)?.unchecked_mul(sign),
FiniteF64::try_from(millis)?.unchecked_mul(sign),
FiniteF64::try_from(micros)?.unchecked_mul(sign),
FiniteF64::try_from(nanos)?.unchecked_mul(sign),
FiniteF64::from(years).copysign(sign),
FiniteF64::from(months).copysign(sign),
FiniteF64::from(weeks).copysign(sign),
FiniteF64::from(days).copysign(sign),
FiniteF64::try_from(hours)?.copysign(sign),
FiniteF64::try_from(minutes)?.copysign(sign),
FiniteF64::try_from(seconds)?.copysign(sign),
FiniteF64::try_from(millis)?.copysign(sign),
FiniteF64::try_from(micros)?.copysign(sign),
FiniteF64::try_from(nanos)?.copysign(sign),
)
}
}
2 changes: 1 addition & 1 deletion src/components/duration/date.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Implementation of a `DateDuration`

use crate::{utils::FiniteF64, Sign, TemporalError, TemporalResult};
use crate::{primitive::FiniteF64, Sign, TemporalError, TemporalResult};

/// `DateDuration` represents the [date duration record][spec] of the `Duration.`
///
Expand Down
2 changes: 1 addition & 1 deletion src/components/duration/normalized.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ use crate::{
components::{tz::TimeZone, Date, DateTime},
iso::IsoDate,
options::{ArithmeticOverflow, ResolvedRoundingOptions, TemporalRoundingMode, TemporalUnit},
primitive::FiniteF64,
rounding::{IncrementRounder, Round},
utils::FiniteF64,
TemporalError, TemporalResult, TemporalUnwrap, NS_PER_DAY,
};

Expand Down
22 changes: 10 additions & 12 deletions src/components/duration/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@ use std::num::NonZeroU128;

use crate::{
options::{ResolvedRoundingOptions, TemporalUnit},
primitive::FiniteF64,
rounding::{IncrementRounder, Round},
temporal_assert,
utils::FiniteF64,
TemporalError, TemporalResult, TemporalUnwrap,
temporal_assert, TemporalError, TemporalResult, TemporalUnwrap,
};

use super::{
Expand All @@ -16,7 +15,7 @@ use super::{
DateDuration,
};

use num_traits::{Euclid, FromPrimitive, MulAdd};
use num_traits::{Euclid, FromPrimitive};

/// `TimeDuration` represents the [Time Duration record][spec] of the `Duration.`
///
Expand Down Expand Up @@ -198,17 +197,16 @@ impl TimeDuration {

// NOTE: days may have the potentially to exceed i64
// 12. Return ! CreateTimeDurationRecord(days × sign, hours × sign, minutes × sign, seconds × sign, milliseconds × sign, microseconds × sign, nanoseconds × sign).
let days = (days as i64).mul_add(sign.into(), 0);
let days = FiniteF64::try_from(days as f64)?.copysign(sign.into());
let result = Self::new_unchecked(
FiniteF64::from((hours as i32).mul_add(sign, 0)),
FiniteF64::from((minutes as i32).mul_add(sign, 0)),
FiniteF64::from((seconds as i32).mul_add(sign, 0)),
FiniteF64::from((milliseconds as i32).mul_add(sign, 0)),
FiniteF64::from((microseconds as i32).mul_add(sign, 0)),
FiniteF64::from((nanoseconds as i32).mul_add(sign, 0)),
FiniteF64::try_from(hours)?.copysign(f64::from(sign)),
FiniteF64::try_from(minutes)?.copysign(f64::from(sign)),
FiniteF64::try_from(seconds)?.copysign(f64::from(sign)),
FiniteF64::try_from(milliseconds)?.copysign(f64::from(sign)),
FiniteF64::try_from(microseconds)?.copysign(f64::from(sign)),
FiniteF64::try_from(nanoseconds)?.copysign(f64::from(sign)),
);

let days = FiniteF64::try_from(days as f64)?;
if !is_valid_duration(
FiniteF64::default(),
FiniteF64::default(),
Expand Down
4 changes: 2 additions & 2 deletions src/components/instant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ use crate::{
RoundingOptions, TemporalUnit,
},
parsers::parse_instant,
primitive::FiniteF64,
rounding::{IncrementRounder, Round},
utils::FiniteF64,
Sign, TemporalError, TemporalResult, TemporalUnwrap,
};

Expand Down Expand Up @@ -321,7 +321,7 @@ mod tests {
use crate::{
components::{duration::TimeDuration, Instant},
options::{DifferenceSettings, TemporalRoundingMode, TemporalUnit},
utils::FiniteF64,
primitive::FiniteF64,
NS_MAX_INSTANT, NS_MIN_INSTANT,
};
use num_traits::ToPrimitive;
Expand Down
2 changes: 1 addition & 1 deletion src/components/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::{
RoundingIncrement, TemporalRoundingMode, TemporalUnit,
},
parsers::parse_time,
utils::FiniteF64,
primitive::FiniteF64,
Sign, TemporalError, TemporalResult,
};

Expand Down
5 changes: 2 additions & 3 deletions src/iso.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,9 @@ use crate::{
},
error::TemporalError,
options::{ArithmeticOverflow, RoundingIncrement, TemporalRoundingMode, TemporalUnit},
primitive::FiniteF64,
rounding::{IncrementRounder, Round},
temporal_assert,
utils::{self, FiniteF64},
TemporalResult, TemporalUnwrap, NS_PER_DAY,
temporal_assert, utils, TemporalResult, TemporalUnwrap, NS_PER_DAY,
};
use icu_calendar::{Date as IcuDate, Iso};
use num_bigint::BigInt;
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ pub mod fields;
pub mod iso;
pub mod options;
pub mod parsers;
pub mod primitive;

#[doc(hidden)]
pub(crate) mod rounding;
Expand Down
138 changes: 138 additions & 0 deletions src/primitive.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
//! Implementation of the FiniteF64 primitive

use crate::{TemporalError, TemporalResult};
use num_traits::{AsPrimitive, FromPrimitive};

#[derive(Debug, Default, Clone, Copy, PartialEq, PartialOrd)]
pub struct FiniteF64(pub(crate) f64);

impl FiniteF64 {
#[inline]
pub fn as_inner(&self) -> f64 {
self.0
}

#[inline]
pub fn is_zero(&self) -> bool {
self.0 == 0.0
}

#[inline]
pub fn negate(&self) -> Self {
if !self.is_zero() {
Self(self.0 * -1.0)
} else {
*self
}
}

#[inline]
pub fn abs(&self) -> Self {
Self(self.0.abs())
}

#[inline]
pub fn checked_add(&self, other: &Self) -> TemporalResult<Self> {
let result = Self(self.0 + other.0);
if !result.0.is_finite() {
return Err(TemporalError::range().with_message("number value is not a finite value."));
}
Ok(result)
}

#[inline]
pub fn checked_mul_add(&self, a: FiniteF64, b: FiniteF64) -> TemporalResult<Self> {
let result = Self(self.0.mul_add(a.0, b.0));
if !result.0.is_finite() {
return Err(TemporalError::range().with_message("number value is not a finite value."));
}
Ok(result)
}

pub fn copysign(&self, other: f64) -> Self {
Self(self.0.copysign(other))
}

pub(crate) fn as_date_value(&self) -> TemporalResult<i32> {
if !(f64::from(i32::MIN)..=f64::from(i32::MAX)).contains(&self.0) {
return Err(TemporalError::range().with_message("number exceeds a valid date value."));
}
Ok(self.0 as i32)
}
}

impl AsPrimitive<i64> for FiniteF64 {
fn as_(self) -> i64 {
self.0 as i64
}
}

impl AsPrimitive<i128> for FiniteF64 {
fn as_(self) -> i128 {
self.0 as i128
}
}

impl TryFrom<f64> for FiniteF64 {
type Error = TemporalError;
fn try_from(value: f64) -> Result<Self, Self::Error> {
if !value.is_finite() {
return Err(TemporalError::range().with_message("number value is not a finite value."));
}
Ok(Self(value))
}
}

impl TryFrom<i128> for FiniteF64 {
type Error = TemporalError;
fn try_from(value: i128) -> Result<Self, Self::Error> {
let result = f64::from_i128(value)
.ok_or(TemporalError::range().with_message("days exceeded a valid range."))?;
if !result.is_finite() {
return Err(TemporalError::range().with_message("number value is not a finite value."));
}
Ok(Self(result))
}
}

impl From<i8> for FiniteF64 {
fn from(value: i8) -> Self {
Self(f64::from(value))
}
}

impl From<i32> for FiniteF64 {
fn from(value: i32) -> Self {
Self(f64::from(value))
}
}

impl From<u8> for FiniteF64 {
fn from(value: u8) -> Self {
Self(f64::from(value))
}
}

impl From<u16> for FiniteF64 {
fn from(value: u16) -> Self {
Self(f64::from(value))
}
}

impl From<u32> for FiniteF64 {
fn from(value: u32) -> Self {
Self(f64::from(value))
}
}

impl PartialEq<f64> for FiniteF64 {
fn eq(&self, other: &f64) -> bool {
self.0 == *other
}
}

impl PartialOrd<f64> for FiniteF64 {
fn partial_cmp(&self, other: &f64) -> Option<std::cmp::Ordering> {
self.0.partial_cmp(other)
}
}
Loading

0 comments on commit fcbadd3

Please sign in to comment.