Skip to content

Commit

Permalink
Add Quantity::as_ and Quantity::cast for changing the underlying stor…
Browse files Browse the repository at this point in the history
…age type.
  • Loading branch information
adamreichold committed Dec 25, 2023
1 parent 629f385 commit 857de2b
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 1 deletion.
4 changes: 3 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,9 @@ pub mod num {
#[cfg(not(feature = "std"))]
pub use num_traits::float::FloatCore as Float;

pub use num_traits::{pow, FromPrimitive, Num, One, Saturating, Signed, ToPrimitive, Zero};
pub use num_traits::{
pow, AsPrimitive, FromPrimitive, Num, NumCast, One, Saturating, Signed, ToPrimitive, Zero,
};

#[cfg(feature = "bigint-support")]
pub use num_bigint::{BigInt, BigUint};
Expand Down
66 changes: 66 additions & 0 deletions src/system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,72 @@ macro_rules! system {
.value()
}}

impl<D, V> Quantity<D, $units<V>, V>
where
D: Dimension + ?Sized,
$units<V>: Units<V>,
V: $crate::num::Num + $crate::Conversion<V>,
{
/// Cast to a quantity with the same dimension and unit but a different underlying
/// storage type allowing for narrowing and precision loss.
///
/// # Examples
#[cfg_attr(all(feature = "si", feature = "f32", feature = "i32"), doc = " ```rust")]
#[cfg_attr(not(all(feature = "si", feature = "f32", feature = "i32")), doc = " ```rust,ignore")]
/// # use uom::si::{f32, i32};
/// # use uom::si::time::second;
/// let t = f32::Time::new::<second>(1.5);
///
/// let t: i32::Time = t.as_();
///
/// assert_eq!(t.get::<second>(), 1);
/// ```
#[inline(always)]
pub fn as_<W>(self) -> Quantity<D, $units<W>, W>
where
V: $crate::num::AsPrimitive<W>,
$units<W>: Units<W>,
W: $crate::num::Num + $crate::Conversion<W> + Copy + 'static,
{
Quantity {
dimension: $crate::lib::marker::PhantomData,
units: $crate::lib::marker::PhantomData,
value: self.value.as_(),
}
}

/// Cast to a quantity with the same dimension and unit but a different underlying
/// storage type allowing for precision loss and truncation.
///
/// # Examples
#[cfg_attr(all(feature = "si", feature = "f32", feature = "i32"), doc = " ```rust")]
#[cfg_attr(not(all(feature = "si", feature = "f32", feature = "i32")), doc = " ```rust,ignore")]
/// # use uom::si::{f32, i32};
/// # use uom::si::time::second;
/// let t1 = f32::Time::new::<second>(1.5);
/// let t2 = f32::Time::new::<second>(1.0e32);
///
/// let t1: Option<i32::Time> = t1.cast();
/// let t2: Option<i32::Time> = t2.cast();
///
/// assert_eq!(t1, Some(i32::Time::new::<second>(1)));
/// assert_eq!(t2, None);
/// ```
#[inline(always)]
pub fn cast<W>(self) -> Option<Quantity<D, $units<W>, W>>
where
V: $crate::num::NumCast,
$units<W>: Units<W>,
W: $crate::num::Num + $crate::Conversion<W> + $crate::num::NumCast,
{
Some(Quantity {
dimension: $crate::lib::marker::PhantomData,
units: $crate::lib::marker::PhantomData,
value: $crate::num::NumCast::from(self.value)?,
})
}
}

#[doc(hidden)]
macro_rules! impl_ops {
(
Expand Down

0 comments on commit 857de2b

Please sign in to comment.