diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 25931be2c..1c074f5f5 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -125,6 +125,12 @@ jobs: - name: Makefile tests run: cd temporal_capi/cpp_tests && make + # There's no guarantee that dependencies are no_std unless you test with a toolchain without `std` + - name: Install no_std toolchain + run: rustup target add thumbv7m-none-eabi + - name: Run no_std tests + run: cargo check -p temporal_capi --target thumbv7m-none-eabi + docs: name: Documentation runs-on: ubuntu-latest diff --git a/Cargo.lock b/Cargo.lock index 6ebff0b67..c549648c6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -893,6 +893,7 @@ name = "temporal_rs" version = "0.0.6" dependencies = [ "combine", + "core_maths", "iana-time-zone", "icu_calendar", "ixdtf", diff --git a/Cargo.toml b/Cargo.toml index d0584121c..e5a1b001a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,7 +28,7 @@ temporal_provider = { version = "~0.0.6", path = "./provider" } tinystr = "0.8.1" icu_calendar = { version = "2.0.0-beta2", default-features = false } rustc-hash = "2.1.0" -num-traits = "0.2.19" +num-traits = { version = "0.2.19", default-features = false } ixdtf = "0.4.0" iana-time-zone = "0.1.63" log = "0.4.27" @@ -71,6 +71,7 @@ combine = { workspace = true, optional = true } # System time feature web-time = { workspace = true, optional = true } +core_maths = "0.1.1" [features] default = ["sys"] diff --git a/src/options/increment.rs b/src/options/increment.rs index 571e1ba28..1fcc66e60 100644 --- a/src/options/increment.rs +++ b/src/options/increment.rs @@ -1,6 +1,7 @@ use core::num::{NonZeroU128, NonZeroU32}; use crate::{TemporalError, TemporalResult}; +use num_traits::float::FloatCore; // ==== RoundingIncrement option ==== @@ -31,7 +32,7 @@ impl TryFrom for RoundingIncrement { } // 5. Let integerIncrement be truncate(ℝ(increment)). - let integer_increment = value.trunc(); + let integer_increment = FloatCore::trunc(value); // 6. If integerIncrement < 1 or integerIncrement > 10**9, throw a RangeError exception. if !(1.0..=1_000_000_000.0).contains(&integer_increment) { return Err(TemporalError::range() diff --git a/src/primitive.rs b/src/primitive.rs index 5e087e23f..2875acdc4 100644 --- a/src/primitive.rs +++ b/src/primitive.rs @@ -1,6 +1,7 @@ //! Implementation of the FiniteF64 primitive use crate::{TemporalError, TemporalResult}; +use num_traits::float::FloatCore; use num_traits::{AsPrimitive, FromPrimitive, PrimInt}; #[derive(Debug, Default, Clone, Copy, PartialEq, PartialOrd)] @@ -48,7 +49,7 @@ impl FiniteF64 { #[inline] pub fn checked_mul_add(&self, a: FiniteF64, b: FiniteF64) -> TemporalResult { - let result = Self(self.0.mul_add(a.0, b.0)); + let result = Self(core_maths::CoreFloat::mul_add(self.0, a.0, b.0)); if !result.0.is_finite() { return Err(TemporalError::range().with_message("number value is not a finite value.")); } @@ -77,7 +78,7 @@ impl FiniteF64 { where f64: AsPrimitive, { - if self.0 != self.0.trunc() { + if self.0 != FloatCore::trunc(self.0) { return Err(TemporalError::range().with_message("value must be integral.")); } Ok(self.0.as_()) diff --git a/src/rounding.rs b/src/rounding.rs index 55f60c36f..f46fcaaa0 100644 --- a/src/rounding.rs +++ b/src/rounding.rs @@ -11,6 +11,7 @@ use core::{ ops::{Div, Neg}, }; +use num_traits::float::FloatCore; use num_traits::{ConstZero, Euclid, FromPrimitive, NumCast, Signed, ToPrimitive}; pub(crate) trait Roundable: @@ -98,14 +99,16 @@ impl Roundable for f64 { fn compare_remainder(dividend: Self, divisor: Self) -> Option { let quotient = Roundable::quotient_abs(dividend, divisor); - let d1 = quotient - quotient.floor(); - let d2 = quotient.ceil() - quotient; + let d1 = quotient - FloatCore::floor(quotient); + let d2 = FloatCore::ceil(quotient) - quotient; d1.partial_cmp(&d2) } fn is_even_cardinal(dividend: Self, divisor: Self) -> bool { let quotient = Roundable::quotient_abs(dividend, divisor); - (quotient.floor() / (quotient.ceil() - quotient.floor()) % 2.0) == 0.0 + (FloatCore::floor(quotient) / (FloatCore::ceil(quotient) - FloatCore::floor(quotient)) + % 2.0) + == 0.0 } fn result_floor(dividend: Self, divisor: Self) -> u128 { diff --git a/temporal_capi/src/calendar.rs b/temporal_capi/src/calendar.rs index 014e6e7c7..db3f4ba31 100644 --- a/temporal_capi/src/calendar.rs +++ b/temporal_capi/src/calendar.rs @@ -9,8 +9,9 @@ pub mod ffi { use crate::plain_date::ffi::{PartialDate, PlainDate}; use crate::plain_month_day::ffi::PlainMonthDay; use crate::plain_year_month::ffi::PlainYearMonth; + use alloc::boxed::Box; + use core::fmt::Write; use diplomat_runtime::DiplomatStr; - use std::fmt::Write; #[diplomat::enum_convert(icu_calendar::any_calendar::AnyCalendarKind, needs_wildcard)] pub enum AnyCalendarKind { diff --git a/temporal_capi/src/duration.rs b/temporal_capi/src/duration.rs index 999fcb17c..35b1faa8a 100644 --- a/temporal_capi/src/duration.rs +++ b/temporal_capi/src/duration.rs @@ -5,6 +5,7 @@ use crate::error::ffi::TemporalError; #[diplomat::attr(auto, namespace = "temporal_rs")] pub mod ffi { use crate::error::ffi::TemporalError; + use alloc::boxed::Box; use diplomat_runtime::DiplomatOption; use num_traits::FromPrimitive; diff --git a/temporal_capi/src/error.rs b/temporal_capi/src/error.rs index 29f8bc481..f385d459b 100644 --- a/temporal_capi/src/error.rs +++ b/temporal_capi/src/error.rs @@ -2,7 +2,6 @@ #[diplomat::abi_rename = "temporal_rs_{0}"] #[diplomat::attr(auto, namespace = "temporal_rs")] pub mod ffi { - #[diplomat::enum_convert(temporal_rs::error::ErrorKind)] pub enum ErrorKind { Generic, diff --git a/temporal_capi/src/instant.rs b/temporal_capi/src/instant.rs index f876951d5..3ad61fb7f 100644 --- a/temporal_capi/src/instant.rs +++ b/temporal_capi/src/instant.rs @@ -5,6 +5,7 @@ pub mod ffi { use crate::duration::ffi::{Duration, TimeDuration}; use crate::error::ffi::TemporalError; use crate::options::ffi::{DifferenceSettings, RoundingOptions}; + use alloc::boxed::Box; #[diplomat::opaque] pub struct Instant(pub temporal_rs::Instant); diff --git a/temporal_capi/src/iso.rs b/temporal_capi/src/iso.rs index fd690412b..e296b6630 100644 --- a/temporal_capi/src/iso.rs +++ b/temporal_capi/src/iso.rs @@ -4,7 +4,6 @@ use temporal_rs::iso; #[diplomat::abi_rename = "temporal_rs_{0}"] #[diplomat::attr(auto, namespace = "temporal_rs")] pub mod ffi { - pub struct IsoDate { pub year: i32, pub month: u8, diff --git a/temporal_capi/src/lib.rs b/temporal_capi/src/lib.rs index 18254da4e..3f35abdaf 100644 --- a/temporal_capi/src/lib.rs +++ b/temporal_capi/src/lib.rs @@ -13,6 +13,10 @@ //! //! [`temporal_rs`]: http://crates.io/crates/temporal_rs +#![no_std] + +extern crate alloc; + pub mod calendar; pub mod duration; pub mod error; diff --git a/temporal_capi/src/plain_date.rs b/temporal_capi/src/plain_date.rs index b50a5af4c..1d1261950 100644 --- a/temporal_capi/src/plain_date.rs +++ b/temporal_capi/src/plain_date.rs @@ -14,8 +14,9 @@ pub mod ffi { use crate::plain_month_day::ffi::PlainMonthDay; use crate::plain_time::ffi::PlainTime; use crate::plain_year_month::ffi::PlainYearMonth; + use alloc::boxed::Box; + use core::fmt::Write; use diplomat_runtime::{DiplomatOption, DiplomatStrSlice, DiplomatWrite}; - use std::fmt::Write; #[diplomat::opaque] pub struct PlainDate(pub(crate) temporal_rs::PlainDate); diff --git a/temporal_capi/src/plain_date_time.rs b/temporal_capi/src/plain_date_time.rs index 9f048e33b..9b90822dc 100644 --- a/temporal_capi/src/plain_date_time.rs +++ b/temporal_capi/src/plain_date_time.rs @@ -7,6 +7,7 @@ pub mod ffi { use crate::calendar::ffi::Calendar; use crate::duration::ffi::Duration; use crate::error::ffi::TemporalError; + use alloc::boxed::Box; use crate::options::ffi::{ ArithmeticOverflow, DifferenceSettings, DisplayCalendar, RoundingOptions, @@ -14,8 +15,8 @@ pub mod ffi { }; use crate::plain_date::ffi::{PartialDate, PlainDate}; use crate::plain_time::ffi::{PartialTime, PlainTime}; + use core::fmt::Write; use diplomat_runtime::DiplomatWrite; - use std::fmt::Write; #[diplomat::opaque] pub struct PlainDateTime(pub(crate) temporal_rs::PlainDateTime); diff --git a/temporal_capi/src/plain_month_day.rs b/temporal_capi/src/plain_month_day.rs index a326eacbb..466dea1f6 100644 --- a/temporal_capi/src/plain_month_day.rs +++ b/temporal_capi/src/plain_month_day.rs @@ -4,12 +4,13 @@ pub mod ffi { use crate::calendar::ffi::Calendar; use crate::error::ffi::TemporalError; + use alloc::boxed::Box; use crate::options::ffi::ArithmeticOverflow; use crate::plain_date::ffi::{PartialDate, PlainDate}; + use core::fmt::Write; use diplomat_runtime::DiplomatWrite; - use std::fmt::Write; #[diplomat::opaque] pub struct PlainMonthDay(pub(crate) temporal_rs::PlainMonthDay); diff --git a/temporal_capi/src/plain_time.rs b/temporal_capi/src/plain_time.rs index 934307ca0..37e416444 100644 --- a/temporal_capi/src/plain_time.rs +++ b/temporal_capi/src/plain_time.rs @@ -2,14 +2,15 @@ #[diplomat::abi_rename = "temporal_rs_{0}"] #[diplomat::attr(auto, namespace = "temporal_rs")] pub mod ffi { + use alloc::boxed::Box; use crate::duration::ffi::{Duration, TimeDuration}; use crate::error::ffi::TemporalError; use crate::options::ffi::{ ArithmeticOverflow, DifferenceSettings, RoundingMode, ToStringRoundingOptions, Unit, }; + use core::fmt::Write; use diplomat_runtime::{DiplomatOption, DiplomatWrite}; - use std::fmt::Write; #[diplomat::opaque] pub struct PlainTime(pub(crate) temporal_rs::PlainTime); diff --git a/temporal_capi/src/plain_year_month.rs b/temporal_capi/src/plain_year_month.rs index afc1ca096..d9a2661dd 100644 --- a/temporal_capi/src/plain_year_month.rs +++ b/temporal_capi/src/plain_year_month.rs @@ -5,11 +5,12 @@ pub mod ffi { use crate::calendar::ffi::Calendar; use crate::duration::ffi::Duration; use crate::error::ffi::TemporalError; + use alloc::boxed::Box; use crate::options::ffi::{ArithmeticOverflow, DifferenceSettings}; use crate::plain_date::ffi::{PartialDate, PlainDate}; + use core::fmt::Write; use diplomat_runtime::DiplomatWrite; - use std::fmt::Write; #[diplomat::opaque] pub struct PlainYearMonth(pub(crate) temporal_rs::PlainYearMonth);