diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a91e404..39bd280 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -49,7 +49,7 @@ jobs: uses: actions-rs/cargo@v1 with: command: test - args: --doc --all-features + args: --doc --features serde - name: Clippy uses: actions-rs/cargo@v1 diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b4d7fe..dfc62d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ ## [Unreleased] +- added optional support for [defmt](https://github.com/knurling-rs/defmt) +- add `scaling_factor` method to `FixedPoint` type to retrieve the const scaling-factor [`Fraction`] from any fixed-point object +- Duration and Rate are no longer implemented by the `Generic` duration and rate types +- durations and rates can now be taken generically by a function without having to bind to `FixedPoint` (`FixedPoint` is now bound to the `Duration` and `Rate` traits) +- `Fraction`s `numerator()` and `denominator()` getter methods now return a value instead of a reference + [unreleased]: https://github.com/FluenTech/embedded-time/compare/v0.12.0...HEAD ## [0.12.0] - 2021-05-30 @@ -13,7 +19,7 @@ ### Changed - limit Rate and Duration extension to u32 -- removed all use os `unwrap()` +- removed all use of `unwrap()` [0.12.0]: https://github.com/FluenTech/embedded-time/compare/v0.11.0...v0.12.0 diff --git a/Cargo.toml b/Cargo.toml index c83ba0c..515694b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "embedded-time" -version = "0.12.0" +version = "0.13.0" authors = ["Peter Taylor "] edition = "2018" description = "Fully defined, inter-operable, ergonomic, and fast human-time units (both duration and rate types) with hardware timer abstraction and software timers." @@ -26,6 +26,7 @@ members = ["examples"] [dependencies] num = { version = "0.3.0", default-features = false } serde = { version = "1.0.0", default-features = false, features = ["derive"], optional = true } +defmt = { version = "0.2.3", optional = true } [dev-dependencies] crossbeam-utils = "0.7.2" diff --git a/src/clock.rs b/src/clock.rs index 2e31ee1..fbc3b59 100644 --- a/src/clock.rs +++ b/src/clock.rs @@ -1,14 +1,15 @@ //! Abstraction for hardware timers/clocks use crate::{ - duration::Duration, fixed_point::FixedPoint, fraction::Fraction, instant::Instant, - time_int::TimeInt, timer::param, timer::Timer, + duration::Duration, fraction::Fraction, instant::Instant, time_int::TimeInt, timer::param, + timer::Timer, }; use core::hash::Hash; /// Potential `Clock` errors #[non_exhaustive] #[derive(Debug, Eq, PartialEq, Hash)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum Error { /// Exact cause of failure is unknown Unspecified, @@ -34,7 +35,11 @@ impl Default for Error { /// software [`Timer`]s can be spawned from a `Clock` object. pub trait Clock: Sized { /// The type to hold the tick count + #[cfg(not(feature = "defmt"))] type T: TimeInt + Hash; + /// The type to hold the tick count + #[cfg(feature = "defmt")] + type T: TimeInt + Hash + defmt::Format; /// The duration of one clock tick in seconds, AKA the clock precision. const SCALING_FACTOR: Fraction; @@ -51,10 +56,7 @@ pub trait Clock: Sized { fn new_timer( &self, duration: Dur, - ) -> Timer - where - Dur: FixedPoint, - { + ) -> Timer { Timer::::new(&self, duration) } } diff --git a/src/duration.rs b/src/duration.rs index 33dec7e..3b0847c 100644 --- a/src/duration.rs +++ b/src/duration.rs @@ -11,6 +11,7 @@ use core::{ convert::TryFrom, hash::{Hash, Hasher}, mem::size_of, + ops, prelude::v1::*, }; #[doc(hidden)] @@ -290,7 +291,7 @@ pub use units::*; /// /// assert_eq!(Minutes(62_u32) % Hours(1_u32), Minutes(2_u32)); /// ``` -pub trait Duration: Sized + Copy { +pub trait Duration: FixedPoint + Sized + Copy { /// Construct a `Generic` `Duration` from a _named_ `Duration` (eg. /// [`Milliseconds`]) /// @@ -340,7 +341,6 @@ pub trait Duration: Sized + Copy { scaling_factor: Fraction, ) -> Result, ConversionError> where - Self: FixedPoint, DestInt: TryFrom, { Ok(Generic::::new( @@ -395,8 +395,6 @@ pub trait Duration: Sized + Copy { /// ``` fn to_rate(&self) -> Result where - Rate: FixedPoint, - Self: FixedPoint, Rate::T: TryFrom, { let conversion_factor = Self::SCALING_FACTOR @@ -406,11 +404,11 @@ pub trait Duration: Sized + Copy { if size_of::() >= size_of::() { fixed_point::FixedPoint::from_ticks( - Self::T::from(*conversion_factor.numerator()) + Self::T::from(conversion_factor.numerator()) .checked_div( &self .integer() - .checked_mul(&Self::T::from(*conversion_factor.denominator())) + .checked_mul(&Self::T::from(conversion_factor.denominator())) .ok_or(ConversionError::Overflow)?, ) .ok_or(ConversionError::DivByZero)?, @@ -418,11 +416,11 @@ pub trait Duration: Sized + Copy { ) } else { fixed_point::FixedPoint::from_ticks( - Rate::T::from(*conversion_factor.numerator()) + Rate::T::from(conversion_factor.numerator()) .checked_div( &Rate::T::try_from(self.integer()) .map_err(|_| ConversionError::Overflow)? - .checked_mul(&Rate::T::from(*conversion_factor.denominator())) + .checked_mul(&Rate::T::from(conversion_factor.denominator())) .ok_or(ConversionError::Overflow)?, ) .ok_or(ConversionError::DivByZero)?, @@ -438,6 +436,7 @@ pub trait Duration: Sized + Copy { /// The purpose of this type is to allow a simple `Duration` object that can be defined at run-time. /// It does this by replacing the `const` _scaling factor_ with a struct field. #[derive(Copy, Clone, Debug, Default)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct Generic { integer: T, scaling_factor: Fraction, @@ -501,7 +500,108 @@ impl Generic { } } -impl Duration for Generic {} +impl Generic { + pub(crate) fn into_ticks(self, fraction: Fraction) -> Result + where + T2: TimeInt, + T2: TryFrom, + { + if size_of::() > size_of::() { + let ticks = + T2::try_from(self.integer()).map_err(|_| ConversionError::ConversionFailure)?; + + if fraction > Fraction::new(1, 1) { + TimeInt::checked_div_fraction( + &TimeInt::checked_mul_fraction(&ticks, &self.scaling_factor) + .ok_or(ConversionError::Unspecified)?, + &fraction, + ) + .ok_or(ConversionError::Unspecified) + } else { + TimeInt::checked_mul_fraction( + &ticks, + &self + .scaling_factor + .checked_div(&fraction) + .ok_or(ConversionError::Unspecified)?, + ) + .ok_or(ConversionError::Unspecified) + } + } else { + let ticks = if self.scaling_factor > Fraction::new(1, 1) { + TimeInt::checked_div_fraction( + &TimeInt::checked_mul_fraction(&self.integer(), &self.scaling_factor) + .ok_or(ConversionError::Unspecified)?, + &fraction, + ) + .ok_or(ConversionError::Unspecified)? + } else { + TimeInt::checked_mul_fraction( + &self.integer(), + &self + .scaling_factor + .checked_div(&fraction) + .ok_or(ConversionError::Unspecified)?, + ) + .ok_or(ConversionError::Unspecified)? + }; + + T2::try_from(ticks).map_err(|_| ConversionError::ConversionFailure) + } + } + + /// Checked addition of two `Generic` durations. + pub fn checked_add_generic(mut self, duration: Generic) -> Option + where + T: TryFrom, + { + let add_ticks: T = duration.into_ticks(*self.scaling_factor()).ok()?; + self.integer = self.integer.checked_add(&add_ticks)?; + + Some(self) + } + + /// Checked subtraction of two `Generic` durations. + pub fn checked_sub_generic(mut self, duration: Generic) -> Option + where + T: TryFrom, + { + let sub_ticks: T = duration.into_ticks(*self.scaling_factor()).ok()?; + self.integer = self.integer.checked_sub(&sub_ticks)?; + + Some(self) + } +} + +impl ops::Add> for Generic +where + T: TryFrom, +{ + type Output = Self; + + fn add(self, rhs: Generic) -> Self::Output { + if let Some(v) = self.checked_add_generic(rhs) { + v + } else { + panic!("Add failed") + } + } +} + +impl ops::Sub> for Generic +where + T: TryFrom, +{ + type Output = Self; + + fn sub(self, rhs: Generic) -> Self::Output { + if let Some(v) = self.checked_sub_generic(rhs) { + v + } else { + panic!("Sub failed") + } + } +} /// Duration units #[doc(hidden)] @@ -560,9 +660,15 @@ pub mod units { } } + #[cfg(feature = "defmt")] + impl defmt::Format for $name { + fn format(&self, fmt: defmt::Formatter) { + defmt::write!(fmt, "{}", self.0) + } + } + impl ops::Add for $name where - Rhs: FixedPoint, Self: TryFrom, { type Output = Self; @@ -576,7 +682,6 @@ pub mod units { impl ops::Sub for $name where Self: TryFrom, - Rhs: FixedPoint, { type Output = Self; @@ -623,7 +728,6 @@ pub mod units { impl ops::Rem for $name where Self: TryFrom, - Rhs: FixedPoint, { type Output = Self; @@ -650,11 +754,38 @@ pub mod units { } } - impl From<$name> for Generic { + impl From<$name> for Generic + where + T1: TimeInt, + T2: TimeInt + From, + { /// See [Converting to a `Generic` /// `Duration`](trait.Duration.html#converting-to-a-generic-duration) - fn from(duration: $name) -> Self { - Self::new(duration.integer(), $name::::SCALING_FACTOR) + fn from(duration: $name) -> Self { + Self::new(duration.integer().into(), $name::::SCALING_FACTOR) + } + } + + impl PartialEq<$name> for Generic + where + T1: TimeInt, + T2: TimeInt + From, + { + fn eq(&self, rhs: &$name) -> bool { + self.eq(rhs.into()) + } + } + + impl PartialOrd<$name> for Generic + where + T1: TimeInt, + T2: TimeInt + From, + { + fn partial_cmp(&self, rhs: &$name) -> Option { + self.partial_cmp(&Self::new( + rhs.integer().into(), + $name::::SCALING_FACTOR, + )) } } }; diff --git a/src/fixed_point.rs b/src/fixed_point.rs index dcb52aa..f633458 100644 --- a/src/fixed_point.rs +++ b/src/fixed_point.rs @@ -29,6 +29,17 @@ pub trait FixedPoint: Sized + Copy { /// ``` fn integer(&self) -> Self::T; + /// Returns the _scaling factor_ [`Fraction`] part + /// + /// ```rust + /// # use embedded_time::{ rate::*}; + /// # + /// assert_eq!(Kilohertz(45_u32).scaling_factor(), Fraction::new(1_000, 1)); + /// ``` + fn scaling_factor(&self) -> Fraction { + Self::SCALING_FACTOR + } + /// Constructs a `FixedPoint` value from _integer_ and _scaling-factor_ ([`Fraction`]) parts /// /// # Errors @@ -146,7 +157,6 @@ pub trait FixedPoint: Sized + Copy { } /// Panicky addition - #[doc(hidden)] fn add(self, rhs: Rhs) -> Self where Self: TryFrom, @@ -160,7 +170,6 @@ pub trait FixedPoint: Sized + Copy { } /// Panicky subtraction - #[doc(hidden)] fn sub(self, rhs: Rhs) -> Self where Self: TryFrom, diff --git a/src/fraction.rs b/src/fraction.rs index 5201c7a..4ae1c8f 100644 --- a/src/fraction.rs +++ b/src/fraction.rs @@ -1,5 +1,6 @@ //! Fractional/Rational values use crate::ConversionError; +use core::cmp::Ordering; use core::ops; use num::{rational::Ratio, CheckedDiv, CheckedMul, Zero}; @@ -12,7 +13,7 @@ use num::{rational::Ratio, CheckedDiv, CheckedMul, Zero}; /// [`Rate`]: rate/trait.Rate.html /// [`Clock`]: clock/trait.Clock.html /// [`Instant`]: instant/struct.Instant.html -#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)] +#[derive(Copy, Clone, Debug)] pub struct Fraction(Ratio); impl Fraction { @@ -25,13 +26,53 @@ impl Fraction { } /// Return the numerator of the fraction - pub const fn numerator(&self) -> &u32 { - self.0.numer() + pub const fn numerator(&self) -> u32 { + *self.0.numer() } /// Return the denominator of the fraction - pub const fn denominator(&self) -> &u32 { - self.0.denom() + pub const fn denominator(&self) -> u32 { + *self.0.denom() + } + + const fn const_eq(&self, other: &Self) -> bool { + (self.numerator() as u64) * (other.denominator() as u64) + == (self.denominator() as u64) * (other.numerator() as u64) + } + + const fn const_cmp(&self, other: &Self) -> Ordering { + let ad = (self.numerator() as u64) * (other.denominator() as u64); + let bc = (self.denominator() as u64) * (other.numerator() as u64); + if ad < bc { + Ordering::Less + } else if ad == bc { + Ordering::Equal + } else { + Ordering::Greater + } + } +} + +impl PartialEq for Fraction { + #[inline(always)] + fn eq(&self, other: &Self) -> bool { + self.const_eq(other) + } +} + +impl Eq for Fraction {} + +impl PartialOrd for Fraction { + #[inline(always)] + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.const_cmp(other)) + } +} + +impl Ord for Fraction { + #[inline(always)] + fn cmp(&self, other: &Self) -> Ordering { + self.const_cmp(other) } } @@ -132,7 +173,7 @@ impl ops::Mul for u64 { /// Panicky u64 × `Fraction` = u64 fn mul(self, rhs: Fraction) -> Self::Output { - (Ratio::new_raw((*rhs.numerator()).into(), (*rhs.denominator()).into()) * self).to_integer() + (Ratio::new_raw(rhs.numerator().into(), rhs.denominator().into()) * self).to_integer() } } @@ -142,7 +183,7 @@ impl ops::Div for u64 { /// Panicky u64 / `Fraction` = u64 #[allow(clippy::suspicious_arithmetic_impl)] fn div(self, rhs: Fraction) -> Self::Output { - (Ratio::new_raw((*rhs.denominator()).into(), (*rhs.numerator()).into()) * self).to_integer() + (Ratio::new_raw(rhs.denominator().into(), rhs.numerator().into()) * self).to_integer() } } @@ -180,5 +221,29 @@ impl Default for Fraction { } } +#[cfg(feature = "defmt")] +impl defmt::Format for Fraction { + fn format(&self, fmt: defmt::Formatter) { + defmt::write!(fmt, "{} / {}", self.numerator(), self.denominator()) + } +} + +use core::hash::{Hash, Hasher}; +impl Hash for Fraction { + fn hash(&self, state: &mut H) { + recurse(self.numerator(), self.denominator(), state); + + fn recurse(numer: u32, denom: u32, state: &mut H) { + if denom != 0 { + let (int, rem) = ((numer / denom), (numer % denom)); + int.hash(state); + recurse(denom, rem, state); + } else { + denom.hash(state); + } + } + } +} + #[cfg(test)] mod tests {} diff --git a/src/instant.rs b/src/instant.rs index 5bd71f1..72cd940 100644 --- a/src/instant.rs +++ b/src/instant.rs @@ -1,8 +1,8 @@ //! An instant of time use crate::{ - duration::{self, Duration}, - fixed_point::FixedPoint, + duration::{self, Duration, Generic}, + time_int::TimeInt, }; use core::{ cmp::Ordering, @@ -46,6 +46,7 @@ use num::traits::{WrappingAdd, WrappingSub}; /// Instant::::new(23); /// ``` #[derive(Debug)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct Instant { ticks: Clock::T, @@ -174,7 +175,6 @@ impl Instant { /// ``` pub fn checked_add(self, duration: Dur) -> Option where - Dur: FixedPoint, Clock::T: TryFrom + core::ops::Div, { let add_ticks: Clock::T = duration.into_ticks(Clock::SCALING_FACTOR).ok()?; @@ -187,6 +187,50 @@ impl Instant { } } + /// `Generic` version of `checked_add`. + /// + /// This `Instant` + [`Duration`] = later (future) `Instant` + /// + /// Returns [`None`] if the [`Duration`] is too large + /// + /// # Examples + /// + /// ```rust + /// # use embedded_time::{fraction::Fraction, duration::*, Instant, ConversionError}; + /// # #[derive(Debug)] + /// struct Clock; + /// impl embedded_time::Clock for Clock { + /// type T = u32; + /// const SCALING_FACTOR: Fraction = Fraction::new(1, 1_000); + /// // ... + /// # fn try_now(&self) -> Result, embedded_time::clock::Error> {unimplemented!()} + /// } + /// + /// assert_eq!( + /// Instant::::new(0).checked_add_generic(Generic::new(1, Fraction::new(1, 1))), + /// Some(Instant::::new(1_000)) + /// ); + /// + /// assert_eq!( + /// Instant::::new(0).checked_add_generic(Generic::new(u32::MAX/2 + 1, Fraction::new(1, 1))), + /// None + /// ); + /// ``` + pub fn checked_add_generic(self, duration: Generic) -> Option + where + Clock::T: TryFrom + core::ops::Div, + Generic: TryFrom>, + { + let add_ticks: Clock::T = duration.into_ticks(Clock::SCALING_FACTOR).ok()?; + if add_ticks <= (::max_value() / 2.into()) { + Some(Self { + ticks: self.ticks.wrapping_add(&add_ticks), + }) + } else { + None + } + } + /// This `Instant` - [`Duration`] = earlier `Instant` /// /// Returns [`None`] if the [`Duration`] is too large @@ -212,7 +256,6 @@ impl Instant { /// ``` pub fn checked_sub(self, duration: Dur) -> Option where - Dur: FixedPoint, Clock::T: TryFrom + core::ops::Div, { let sub_ticks: Clock::T = duration.into_ticks(Clock::SCALING_FACTOR).ok()?; @@ -224,6 +267,46 @@ impl Instant { None } } + + /// `Generic` version of `checked_sub`. + /// + /// This `Instant` - [`Duration`] = earlier `Instant` + /// + /// Returns [`None`] if the [`Duration`] is too large + /// + /// # Examples + /// + /// ```rust + /// # use embedded_time::{fraction::Fraction, duration::*, Instant, ConversionError}; + /// # #[derive(Debug)] + /// struct Clock; + /// impl embedded_time::Clock for Clock { + /// type T = u32; + /// const SCALING_FACTOR: Fraction = Fraction::new(1, 1_000); + /// // ... + /// # fn try_now(&self) -> Result, embedded_time::clock::Error> {unimplemented!()} + /// } + /// + /// assert_eq!(Instant::::new(1_000).checked_sub_generic(Generic::new(1, Fraction::new(1, 1))), + /// Some(Instant::::new(0))); + /// + /// assert_eq!(Instant::::new(u32::MAX).checked_sub_generic(Generic::new(u32::MAX/2 + 1, Fraction::new(1, 1))), + /// None); + /// ``` + pub fn checked_sub_generic(self, duration: Generic) -> Option + where + Clock::T: TryFrom + core::ops::Div, + Generic: TryFrom>, + { + let sub_ticks: Clock::T = duration.into_ticks(Clock::SCALING_FACTOR).ok()?; + if sub_ticks <= (::max_value() / 2.into()) { + Some(Self { + ticks: self.ticks.wrapping_sub(&sub_ticks), + }) + } else { + None + } + } } impl Copy for Instant {} @@ -261,7 +344,7 @@ impl PartialOrd for Instant { /// assert!(Instant::::new(u32::MAX) < Instant::::new(u32::MIN)); /// ``` fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(&other)) + Some(self.cmp(other)) } } @@ -281,7 +364,6 @@ where impl ops::Add for Instant where Clock::T: TryFrom, - Dur: FixedPoint, { type Output = Self; @@ -340,10 +422,25 @@ where } } +impl ops::Add> for Instant +where + Generic: TryFrom>, + Clock::T: TryFrom, +{ + type Output = Self; + + fn add(self, rhs: Generic) -> Self::Output { + if let Some(v) = self.checked_add_generic(rhs) { + v + } else { + panic!("Add failed") + } + } +} + impl ops::Sub for Instant where Clock::T: TryFrom, - Dur: FixedPoint, { type Output = Self; @@ -402,6 +499,22 @@ where } } +impl ops::Sub> for Instant +where + Generic: TryFrom>, + Clock::T: TryFrom, +{ + type Output = Self; + + fn sub(self, rhs: Generic) -> Self::Output { + if let Some(v) = self.checked_sub_generic(rhs) { + v + } else { + panic!("Sub failed") + } + } +} + impl ops::Sub> for Instant { type Output = duration::Generic; diff --git a/src/lib.rs b/src/lib.rs index 85be10a..1e05539 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -272,7 +272,7 @@ //! - [`RTIC`](https://github.com/rtic-rs/cortex-m-rtic) //! - [`time`](https://docs.rs/time/latest/time) (Specifically the [`time::NumbericalDuration`](https://docs.rs/time/latest/time/trait.NumericalDuration.html) //! implementations for primitive integers) -#![doc(html_root_url = "https://docs.rs/embedded-time/0.12.0")] +#![doc(html_root_url = "https://docs.rs/embedded-time/0.13.0")] #![deny(unsafe_code)] #![cfg_attr(not(test), no_std)] #![warn(missing_docs)] @@ -295,6 +295,7 @@ pub use timer::Timer; /// Crate errors #[non_exhaustive] #[derive(Debug, Eq, PartialEq, Hash)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum TimeError { /// Exact cause of failure is unknown Unspecified, @@ -325,6 +326,7 @@ impl Default for TimeError { /// Conversion errors #[non_exhaustive] #[derive(Debug, Eq, PartialEq, Hash)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum ConversionError { /// Exact cause of failure is unknown Unspecified, diff --git a/src/rate.rs b/src/rate.rs index a64bb13..2392e0e 100644 --- a/src/rate.rs +++ b/src/rate.rs @@ -197,7 +197,7 @@ pub use units::*; /// /// assert_eq!(Hertz(2_037_u32) % Kilohertz(1_u32), Hertz(37_u32)); /// ``` -pub trait Rate: Sized + Copy { +pub trait Rate: FixedPoint + Sized + Copy { /// Construct a `Generic` `Rate` from a _named_ `Rate` (eg. [`Kilohertz`]) /// /// # Examples @@ -248,7 +248,6 @@ pub trait Rate: Sized + Copy { scaling_factor: Fraction, ) -> Result, ConversionError> where - Self: FixedPoint, DestInt: TryFrom, { Ok(Generic::::new( @@ -303,8 +302,6 @@ pub trait Rate: Sized + Copy { /// ``` fn to_duration(&self) -> Result where - Duration: FixedPoint, - Self: FixedPoint, Duration::T: TryFrom, { let conversion_factor = Self::SCALING_FACTOR @@ -314,11 +311,11 @@ pub trait Rate: Sized + Copy { if size_of::() >= size_of::() { fixed_point::FixedPoint::from_ticks( - Self::T::from(*conversion_factor.numerator()) + Self::T::from(conversion_factor.numerator()) .checked_div( &self .integer() - .checked_mul(&Self::T::from(*conversion_factor.denominator())) + .checked_mul(&Self::T::from(conversion_factor.denominator())) .ok_or(ConversionError::Overflow)?, ) .ok_or(ConversionError::DivByZero)?, @@ -326,11 +323,11 @@ pub trait Rate: Sized + Copy { ) } else { fixed_point::FixedPoint::from_ticks( - Duration::T::from(*conversion_factor.numerator()) + Duration::T::from(conversion_factor.numerator()) .checked_div( &Duration::T::try_from(self.integer()) .map_err(|_| ConversionError::Overflow)? - .checked_mul(&Duration::T::from(*conversion_factor.denominator())) + .checked_mul(&Duration::T::from(conversion_factor.denominator())) .ok_or(ConversionError::Overflow)?, ) .ok_or(ConversionError::DivByZero)?, @@ -371,8 +368,6 @@ impl Generic { } } -impl Rate for Generic {} - /// Rate-type units #[doc(hidden)] pub mod units { @@ -432,7 +427,6 @@ pub mod units { impl ops::Add for $name where - Rhs: FixedPoint, Self: TryFrom, { type Output = Self; @@ -446,7 +440,6 @@ pub mod units { impl ops::Sub for $name where Self: TryFrom, - Rhs: FixedPoint, { type Output = Self; @@ -477,7 +470,6 @@ pub mod units { impl ops::Rem for $name where Self: TryFrom, - Rhs: FixedPoint, { type Output = Self; diff --git a/src/time_int.rs b/src/time_int.rs index 66e1832..2090a27 100644 --- a/src/time_int.rs +++ b/src/time_int.rs @@ -22,8 +22,8 @@ pub trait TimeInt: /// /// Returns truncated (rounded toward `0`) integer or [`None`] upon failure fn checked_mul_fraction(&self, fraction: &Fraction) -> Option { - self.checked_mul(&(*fraction.numerator()).into())? - .checked_div(&(*fraction.denominator()).into()) + self.checked_mul(&fraction.numerator().into())? + .checked_div(&fraction.denominator().into()) } /// Checked integer / [`Fraction`] = integer diff --git a/src/timer.rs b/src/timer.rs index ff76cf9..7d3b695 100644 --- a/src/timer.rs +++ b/src/timer.rs @@ -3,7 +3,6 @@ use crate::fraction::Fraction; use crate::{ duration::{self, *}, - fixed_point::FixedPoint, timer::param::*, ConversionError, Instant, TimeError, }; @@ -13,28 +12,34 @@ use core::{convert::TryFrom, marker::PhantomData, ops::Add, prelude::v1::*}; pub mod param { /// Parameter not set #[derive(Debug, Hash)] + #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct None; /// Timer is ready to start #[derive(Debug, Hash)] + #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct Armed; /// Timer is running #[derive(Debug, Hash)] + #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct Running; /// Timer will automatically restart when it expires #[derive(Debug, Hash)] + #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct Periodic; /// Timer will stop when it expires #[derive(Debug, Hash)] + #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct OneShot; } /// A `Timer` counts toward an expiration, can be polled for elapsed and remaining time, and can be /// one-shot or continuous/periodic. #[derive(Debug, Hash)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct Timer<'a, Type, State, Clock: crate::Clock, Dur: Duration> { clock: &'a Clock, duration: Dur, @@ -86,7 +91,6 @@ impl<'a, Type, Clock: crate::Clock, Dur: Duration> Timer<'a, Type, Armed, Clock, pub fn start(self) -> Result, TimeError> where Clock::T: TryFrom, - Dur: FixedPoint, { Ok(Timer:: { clock: self.clock, @@ -114,7 +118,7 @@ impl Timer<'_, Type, Running, Clock, D /// The units of the [`Duration`] are the same as that used to construct the `Timer`. pub fn elapsed(&self) -> Result where - Dur: FixedPoint + TryFrom, Error = ConversionError>, + Dur: TryFrom, Error = ConversionError>, Dur::T: TryFrom, Clock::T: TryFrom, { @@ -139,7 +143,7 @@ impl Timer<'_, Type, Running, Clock, D /// The units of the [`Duration`] are the same as that used to construct the `Timer`. pub fn remaining(&self) -> Result where - Dur: FixedPoint + TryFrom, Error = ConversionError>, + Dur: TryFrom, Error = ConversionError>, Dur::T: TryFrom + TryFrom, Clock::T: TryFrom, { diff --git a/tests/duration.rs b/tests/duration.rs index 2137956..6970ac5 100644 --- a/tests/duration.rs +++ b/tests/duration.rs @@ -50,8 +50,9 @@ fn comparisons() { assert!(Microseconds(5_u32) < Microseconds(u64::MAX)); assert!(Microseconds(u64::MAX) > Microseconds(5_u32)); - assert!(Generic::new(32_768, Fraction::new(1, 32_768)) < Milliseconds(10_000_u32).into()); - assert!(Generic::new(20 * 32_768, Fraction::new(1, 32_768)) > Milliseconds(10_000_u32).into()); + assert!(Generic::new(32_768_u64, Fraction::new(1, 32_768)) < Milliseconds(10_000_u32)); + assert!(Generic::new(32_768_u32, Fraction::new(1, 32_768)) < Milliseconds(10_000_u32)); + assert!(Generic::new(20 * 32_768_u32, Fraction::new(1, 32_768)) > Milliseconds(10_000_u32)); assert!( Generic::new(1_000u32, Fraction::new(1, 1_000)) == Generic::new(2_000u32, Fraction::new(1, 2_000)) @@ -64,6 +65,11 @@ fn add() { (Milliseconds(1_u32) + Seconds(1_u32)), Milliseconds(1_001_u32) ); + + assert_eq!( + (Generic::new(1_010u32, Fraction::new(1, 1_000)) + Generic::new(1u32, Fraction::new(1, 1))), + Generic::new(2_010u32, Fraction::new(1, 1_000)) + ); } #[test] @@ -74,6 +80,11 @@ fn sub() { ); assert_eq!(Minutes(u32::MAX) - Hours(1_u32), Minutes(u32::MAX - 60)); + + assert_eq!( + (Generic::new(1_010u32, Fraction::new(1, 1_000)) - Generic::new(1u32, Fraction::new(1, 1))), + Generic::new(10u32, Fraction::new(1, 1_000)) + ); } #[test] @@ -282,40 +293,40 @@ fn into_bigger() { assert_eq!( $into::::from($small(u32::MAX)), $into((u32::MAX as u64 - * *$small::::SCALING_FACTOR.numerator() as u64 - * *$into::::SCALING_FACTOR.denominator() as u64 - / *$into::::SCALING_FACTOR.numerator() as u64 - / *$small::::SCALING_FACTOR.denominator() as u64 + * $small::::SCALING_FACTOR.numerator() as u64 + * $into::::SCALING_FACTOR.denominator() as u64 + / $into::::SCALING_FACTOR.numerator() as u64 + / $small::::SCALING_FACTOR.denominator() as u64 ) as u32) ); let rate: $into = $small(u32::MAX).into(); assert_eq!(rate, $into((u32::MAX as u64 - * *$small::::SCALING_FACTOR.numerator() as u64 - * *$into::::SCALING_FACTOR.denominator() as u64 - / *$into::::SCALING_FACTOR.numerator() as u64 - / *$small::::SCALING_FACTOR.denominator() as u64 + * $small::::SCALING_FACTOR.numerator() as u64 + * $into::::SCALING_FACTOR.denominator() as u64 + / $into::::SCALING_FACTOR.numerator() as u64 + / $small::::SCALING_FACTOR.denominator() as u64 ) as u32) ); assert_eq!( $into::::from($small(u32::MAX)), $into((u32::MAX as u64 - * *$small::::SCALING_FACTOR.numerator() as u64 - * *$into::::SCALING_FACTOR.denominator() as u64 - / *$into::::SCALING_FACTOR.numerator() as u64 - / *$small::::SCALING_FACTOR.denominator() as u64 + * $small::::SCALING_FACTOR.numerator() as u64 + * $into::::SCALING_FACTOR.denominator() as u64 + / $into::::SCALING_FACTOR.numerator() as u64 + / $small::::SCALING_FACTOR.denominator() as u64 ) as u64) ); let rate: $into = $small(u32::MAX).into(); assert_eq!(rate, $into((u32::MAX as u64 - * *$small::::SCALING_FACTOR.numerator() as u64 - * *$into::::SCALING_FACTOR.denominator() as u64 - / *$into::::SCALING_FACTOR.numerator() as u64 - / *$small::::SCALING_FACTOR.denominator() as u64 + * $small::::SCALING_FACTOR.numerator() as u64 + * $into::::SCALING_FACTOR.denominator() as u64 + / $into::::SCALING_FACTOR.numerator() as u64 + / $small::::SCALING_FACTOR.denominator() as u64 ) as u64) ); @@ -323,10 +334,10 @@ fn into_bigger() { $into::::try_from($small(u32::MAX as u64)), Ok( $into((u32::MAX as u64 - * *$small::::SCALING_FACTOR.numerator() as u64 - * *$into::::SCALING_FACTOR.denominator() as u64 - / *$into::::SCALING_FACTOR.numerator() as u64 - / *$small::::SCALING_FACTOR.denominator() as u64 + * $small::::SCALING_FACTOR.numerator() as u64 + * $into::::SCALING_FACTOR.denominator() as u64 + / $into::::SCALING_FACTOR.numerator() as u64 + / $small::::SCALING_FACTOR.denominator() as u64 ) as u32) ) ); @@ -336,10 +347,10 @@ fn into_bigger() { rate, Ok( $into((u32::MAX as u64 - * *$small::::SCALING_FACTOR.numerator() as u64 - * *$into::::SCALING_FACTOR.denominator() as u64 - / *$into::::SCALING_FACTOR.numerator() as u64 - / *$small::::SCALING_FACTOR.denominator() as u64 + * $small::::SCALING_FACTOR.numerator() as u64 + * $into::::SCALING_FACTOR.denominator() as u64 + / $into::::SCALING_FACTOR.numerator() as u64 + / $small::::SCALING_FACTOR.denominator() as u64 ) as u32) ) ); @@ -393,20 +404,20 @@ fn into_smaller() { assert_eq!( $into::::from($big(u32::MAX)), $into((u32::MAX as u64 - * *$big::::SCALING_FACTOR.numerator() as u64 - * *$into::::SCALING_FACTOR.denominator() as u64 - / *$into::::SCALING_FACTOR.numerator() as u64 - / *$big::::SCALING_FACTOR.denominator() as u64 + * $big::::SCALING_FACTOR.numerator() as u64 + * $into::::SCALING_FACTOR.denominator() as u64 + / $into::::SCALING_FACTOR.numerator() as u64 + / $big::::SCALING_FACTOR.denominator() as u64 ) as u64) ); let rate: $into = $big(u32::MAX).into(); assert_eq!(rate, $into((u32::MAX as u64 - * *$big::::SCALING_FACTOR.numerator() as u64 - * *$into::::SCALING_FACTOR.denominator() as u64 - / *$into::::SCALING_FACTOR.numerator() as u64 - / *$big::::SCALING_FACTOR.denominator() as u64 + * $big::::SCALING_FACTOR.numerator() as u64 + * $into::::SCALING_FACTOR.denominator() as u64 + / $into::::SCALING_FACTOR.numerator() as u64 + / $big::::SCALING_FACTOR.denominator() as u64 ) as u64) ); @@ -414,10 +425,10 @@ fn into_smaller() { $into::::try_from($big(4 as u32)), Ok( $into((4 as u64 - * *$big::::SCALING_FACTOR.numerator() as u64 - * *$into::::SCALING_FACTOR.denominator() as u64 - / *$into::::SCALING_FACTOR.numerator() as u64 - / *$big::::SCALING_FACTOR.denominator() as u64 + * $big::::SCALING_FACTOR.numerator() as u64 + * $into::::SCALING_FACTOR.denominator() as u64 + / $into::::SCALING_FACTOR.numerator() as u64 + / $big::::SCALING_FACTOR.denominator() as u64 ) as u32) ) ); @@ -427,10 +438,10 @@ fn into_smaller() { rate, Ok( $into((4 as u64 - * *$big::::SCALING_FACTOR.numerator() as u64 - * *$into::::SCALING_FACTOR.denominator() as u64 - / *$into::::SCALING_FACTOR.numerator() as u64 - / *$big::::SCALING_FACTOR.denominator() as u64 + * $big::::SCALING_FACTOR.numerator() as u64 + * $into::::SCALING_FACTOR.denominator() as u64 + / $into::::SCALING_FACTOR.numerator() as u64 + / $big::::SCALING_FACTOR.denominator() as u64 ) as u32) ) ); @@ -439,10 +450,10 @@ fn into_smaller() { $into::::try_from($big(4 as u64)), Ok( $into((4 as u64 - * *$big::::SCALING_FACTOR.numerator() as u64 - * *$into::::SCALING_FACTOR.denominator() as u64 - / *$into::::SCALING_FACTOR.numerator() as u64 - / *$big::::SCALING_FACTOR.denominator() as u64 + * $big::::SCALING_FACTOR.numerator() as u64 + * $into::::SCALING_FACTOR.denominator() as u64 + / $into::::SCALING_FACTOR.numerator() as u64 + / $big::::SCALING_FACTOR.denominator() as u64 ) as u32) ) ); @@ -452,10 +463,10 @@ fn into_smaller() { rate, Ok( $into((4 as u64 - * *$big::::SCALING_FACTOR.numerator() as u64 - * *$into::::SCALING_FACTOR.denominator() as u64 - / *$into::::SCALING_FACTOR.numerator() as u64 - / *$big::::SCALING_FACTOR.denominator() as u64 + * $big::::SCALING_FACTOR.numerator() as u64 + * $into::::SCALING_FACTOR.denominator() as u64 + / $into::::SCALING_FACTOR.numerator() as u64 + / $big::::SCALING_FACTOR.denominator() as u64 ) as u32) ) ); @@ -464,10 +475,10 @@ fn into_smaller() { $into::::try_from($big(4 as u64)), Ok( $into((4 as u64 - * *$big::::SCALING_FACTOR.numerator() as u64 - * *$into::::SCALING_FACTOR.denominator() as u64 - / *$into::::SCALING_FACTOR.numerator() as u64 - / *$big::::SCALING_FACTOR.denominator() as u64 + * $big::::SCALING_FACTOR.numerator() as u64 + * $into::::SCALING_FACTOR.denominator() as u64 + / $into::::SCALING_FACTOR.numerator() as u64 + / $big::::SCALING_FACTOR.denominator() as u64 ) as u64) ) ); @@ -477,10 +488,10 @@ fn into_smaller() { rate, Ok( $into((4 as u64 - * *$big::::SCALING_FACTOR.numerator() as u64 - * *$into::::SCALING_FACTOR.denominator() as u64 - / *$into::::SCALING_FACTOR.numerator() as u64 - / *$big::::SCALING_FACTOR.denominator() as u64 + * $big::::SCALING_FACTOR.numerator() as u64 + * $into::::SCALING_FACTOR.denominator() as u64 + / $into::::SCALING_FACTOR.numerator() as u64 + / $big::::SCALING_FACTOR.denominator() as u64 ) as u64) ) ); diff --git a/tests/fraction.rs b/tests/fraction.rs index ae6868c..49fd899 100644 --- a/tests/fraction.rs +++ b/tests/fraction.rs @@ -6,7 +6,7 @@ use test_case::test_case; #[test_case((6, 0) => Err(ConversionError::DivByZero) ; "A denominator of 0 will fail")] fn new_reduce(fraction: (u32, u32)) -> Result<(u32, u32), ConversionError> { Fraction::new_reduce(fraction.0, fraction.1) - .map(|fraction| (*fraction.numerator(), *fraction.denominator())) + .map(|fraction| (fraction.numerator(), fraction.denominator())) } #[test_case((3, 1) => 3 ; "Returns integer, no truncation required")] @@ -18,7 +18,7 @@ fn to_integer(fraction: (u32, u32)) -> u32 { #[test_case(3 => (3,1) ; "Returns integer as fraction")] fn from_integer(integer: u32) -> (u32, u32) { let fraction = Fraction::from_integer(integer); - (*fraction.numerator(), *fraction.denominator()) + (fraction.numerator(), fraction.denominator()) } #[test_case(u32::MAX, (3,5) => u32::MAX / 5 * 3 ; "Properly handles potential overflows when possible")] @@ -36,8 +36,8 @@ fn u64_mul_fraction(integer: u64, fraction: (u32, u32)) -> u64 { #[test] fn fraction_mul_fraction() { let product = Fraction::new(1_000, 1) * Fraction::new(5, 5); - assert_eq!(*product.numerator(), 1_000_u32); - assert_eq!(*product.denominator(), 1_u32); + assert_eq!(product.numerator(), 1_000_u32); + assert_eq!(product.denominator(), 1_u32); } #[test_case(12, (4,3) => 9 ; "Returns integer result")] @@ -57,6 +57,6 @@ fn u64_div_fraction(integer: u64, fraction: (u32, u32)) -> u64 { #[test] fn fraction_div_fraction() { let product = Fraction::new(1_000, 1) / Fraction::new(10, 1_000); - assert_eq!(*product.numerator(), 100_000_u32); - assert_eq!(*product.denominator(), 1_u32); + assert_eq!(product.numerator(), 100_000_u32); + assert_eq!(product.denominator(), 1_u32); } diff --git a/tests/instant.rs b/tests/instant.rs index ee92a10..5305c56 100644 --- a/tests/instant.rs +++ b/tests/instant.rs @@ -82,14 +82,20 @@ fn duration_add_instant(base: u32, addition: u32) -> Instant { Milliseconds(base) + Instant::::new(addition) } -#[test_case(0, u32::MAX/2 => Some(Instant::::new(u32::MAX / 2)) ; "Add the maximum allowed duration")] -#[test_case(0, u32::MAX/2 + 1 => None ; "Overflow due to the duration being too large")] -fn checked_add(base: u32, addition: u32) -> Option> { - Instant::::new(base).checked_add(Milliseconds(addition)) +#[test_case(0, Milliseconds(u32::MAX/2) => Some(Instant::::new(u32::MAX / 2)) ; "Add the maximum allowed duration")] +#[test_case(0, Milliseconds(u32::MAX/2 + 1) => None ; "Overflow due to the duration being too large")] +fn checked_add(base: u32, addition: Dur) -> Option> +where + Dur::T: Into, +{ + Instant::::new(base).checked_add(addition) } -#[test_case(u32::MAX, u32::MAX/2 => Some(Instant::::new(u32::MAX - (u32::MAX / 2))) ; "Subtract the maximum allowed duration")] -#[test_case(u32::MAX, u32::MAX/2 + 1 => None ; "Overflow due to the duration being too large")] -fn checked_sub(base: u32, subtrahend: u32) -> Option> { - Instant::::new(base).checked_sub(Milliseconds(subtrahend)) +#[test_case(u32::MAX, Milliseconds(u32::MAX/2) => Some(Instant::::new(u32::MAX - (u32::MAX / 2))) ; "Subtract the maximum allowed duration")] +#[test_case(u32::MAX, Milliseconds(u32::MAX/2 + 1) => None ; "Overflow due to the duration being too large")] +fn checked_sub(base: u32, subtrahend: Dur) -> Option> +where + Dur::T: Into, +{ + Instant::::new(base).checked_sub(subtrahend) } diff --git a/tests/rate.rs b/tests/rate.rs index 21b0300..644174a 100644 --- a/tests/rate.rs +++ b/tests/rate.rs @@ -225,27 +225,27 @@ fn into_bigger() { $( assert_eq!( $into::::from($small(u32::MAX)), - $into((u32::MAX as u64 * *$small::::SCALING_FACTOR.numerator() as u64 / *$into::::SCALING_FACTOR.numerator() as u64) as u32) + $into((u32::MAX as u64 * $small::::SCALING_FACTOR.numerator() as u64 / $into::::SCALING_FACTOR.numerator() as u64) as u32) ); let rate: $into = $small(u32::MAX).into(); - assert_eq!(rate, $into((u32::MAX as u64 * *$small::::SCALING_FACTOR.numerator() as u64 / *$into::::SCALING_FACTOR.numerator() as u64) as u32)); + assert_eq!(rate, $into((u32::MAX as u64 * $small::::SCALING_FACTOR.numerator() as u64 / $into::::SCALING_FACTOR.numerator() as u64) as u32)); assert_eq!( $into::::from($small(u32::MAX)), - $into((u32::MAX as u64 * *$small::::SCALING_FACTOR.numerator() as u64 / *$into::::SCALING_FACTOR.numerator() as u64) as u32) + $into((u32::MAX as u64 * $small::::SCALING_FACTOR.numerator() as u64 / $into::::SCALING_FACTOR.numerator() as u64) as u32) ); let rate: $into = $small(u32::MAX).into(); - assert_eq!(rate, $into((u32::MAX as u64 * *$small::::SCALING_FACTOR.numerator() as u64 / *$into::::SCALING_FACTOR.numerator() as u64) as u32)); + assert_eq!(rate, $into((u32::MAX as u64 * $small::::SCALING_FACTOR.numerator() as u64 / $into::::SCALING_FACTOR.numerator() as u64) as u32)); assert_eq!( $into::::try_from($small(u32::MAX as u64)), - Ok($into((u32::MAX as u64 * *$small::::SCALING_FACTOR.numerator() as u64 / *$into::::SCALING_FACTOR.numerator() as u64) as u32)) + Ok($into((u32::MAX as u64 * $small::::SCALING_FACTOR.numerator() as u64 / $into::::SCALING_FACTOR.numerator() as u64) as u32)) ); let rate: Result<$into, _> = $small(u32::MAX as u64).try_into(); - assert_eq!(rate, Ok($into((u32::MAX as u64 * *$small::::SCALING_FACTOR.numerator() as u64 / *$into::::SCALING_FACTOR.numerator() as u64) as u32))); + assert_eq!(rate, Ok($into((u32::MAX as u64 * $small::::SCALING_FACTOR.numerator() as u64 / $into::::SCALING_FACTOR.numerator() as u64) as u32))); )+ test_into_bigger!($($small),+); @@ -324,38 +324,38 @@ fn into_smaller() { $( assert_eq!( $into::::from($big(u32::MAX)), - $into(u32::MAX as u64 * *$big::::SCALING_FACTOR.numerator() as u64 / *$into::::SCALING_FACTOR.numerator() as u64) + $into(u32::MAX as u64 * $big::::SCALING_FACTOR.numerator() as u64 / $into::::SCALING_FACTOR.numerator() as u64) ); let rate: $into = $big(u32::MAX).into(); - assert_eq!(rate, $into(u32::MAX as u64 * *$big::::SCALING_FACTOR.numerator() as u64 / *$into::::SCALING_FACTOR.numerator() as u64)); + assert_eq!(rate, $into(u32::MAX as u64 * $big::::SCALING_FACTOR.numerator() as u64 / $into::::SCALING_FACTOR.numerator() as u64)); // big to small assert_eq!( $into::::try_from($big(500 as u64)), - Ok($into((500 as u64 * *$big::::SCALING_FACTOR.numerator() as u64 / *$into::::SCALING_FACTOR.numerator() as u64) as u32)) + Ok($into((500 as u64 * $big::::SCALING_FACTOR.numerator() as u64 / $into::::SCALING_FACTOR.numerator() as u64) as u32)) ); let rate: Result<$into, _> = $big(500 as u64).try_into(); - assert_eq!(rate, Ok($into((500 as u64 * *$big::::SCALING_FACTOR.numerator() as u64 / *$into::::SCALING_FACTOR.numerator() as u64) as u32))); + assert_eq!(rate, Ok($into((500 as u64 * $big::::SCALING_FACTOR.numerator() as u64 / $into::::SCALING_FACTOR.numerator() as u64) as u32))); // big to small assert_eq!( $into::::try_from($big(500 as u64)), - Ok($into((500 as u64 * *$big::::SCALING_FACTOR.numerator() as u64 / *$into::::SCALING_FACTOR.numerator() as u64) as u64)) + Ok($into((500 as u64 * $big::::SCALING_FACTOR.numerator() as u64 / $into::::SCALING_FACTOR.numerator() as u64) as u64)) ); let rate: Result<$into, _> = $big(500 as u64).try_into(); - assert_eq!(rate, Ok($into((500 as u64 * *$big::::SCALING_FACTOR.numerator() as u64 / *$into::::SCALING_FACTOR.numerator() as u64) as u64))); + assert_eq!(rate, Ok($into((500 as u64 * $big::::SCALING_FACTOR.numerator() as u64 / $into::::SCALING_FACTOR.numerator() as u64) as u64))); // big to small assert_eq!( $into::::try_from($big(500 as u32)), - Ok($into((500 as u64 * *$big::::SCALING_FACTOR.numerator() as u64 / *$into::::SCALING_FACTOR.numerator() as u64) as u32)) + Ok($into((500 as u64 * $big::::SCALING_FACTOR.numerator() as u64 / $into::::SCALING_FACTOR.numerator() as u64) as u32)) ); let rate: Result<$into, _> = $big(500 as u32).try_into(); - assert_eq!(rate, Ok($into((500 as u64 * *$big::::SCALING_FACTOR.numerator() as u64 / *$into::::SCALING_FACTOR.numerator() as u64) as u32))); + assert_eq!(rate, Ok($into((500 as u64 * $big::::SCALING_FACTOR.numerator() as u64 / $into::::SCALING_FACTOR.numerator() as u64) as u32))); )+ test_into_smaller!($($big),+); diff --git a/tests/timer.rs b/tests/timer.rs index 515bcf0..8d60db0 100644 --- a/tests/timer.rs +++ b/tests/timer.rs @@ -1,7 +1,5 @@ use crossbeam_utils::thread; -use embedded_time::{ - self as time, duration::*, fixed_point, fraction::Fraction, Clock as _, Instant, -}; +use embedded_time::{self as time, duration::*, fraction::Fraction, Clock as _, Instant}; use std::sync::atomic::{AtomicU64, Ordering}; static TICKS: AtomicU64 = AtomicU64::new(0); @@ -127,7 +125,6 @@ fn init_ticks() {} fn add_to_ticks(duration: Dur) where - Dur: fixed_point::FixedPoint, u64: From, { let ticks = TICKS.load(Ordering::SeqCst);