Struct yaiouom::Measure
[−]
[src]
pub struct Measure<T, U: Unit> { /* fields omitted */ }
A value with a unit.
Methods
impl<T, U: Unit> Measure<T, U>
[src]
pub fn new(value: T) -> Self
[src]
Convert from a dimensionless unit.
use yaiouom::*; use yaiouom::si::*; let one_meter : Measure<_, Meter> = Measure::new(1);
Warning
This function is somewhat unsafe, as you can use it to build values that are fully polymorphic in unit.
Future versions will make this constructor private and hide it behind syntactic sugar.
pub fn unify<V: Unit>(self) -> Measure<T, V>
[src]
Compare two units of measure (not their values).
Out of the box, the Rust type system is not powerful enough to resolve
general equality between two units of measure. So, for instance, it
will not realize that m * s
and s * m
are the same unit, or that
m / m
is the same as the dimensionless unit.
For instance, the following will fail to type:
use yaiouom::*; use yaiouom::si::*; let one_meter = Meter::new(1); let one_second = Second::new(1); let a = one_meter * one_second; let b = one_second * one_meter; assert_eq!(a, b); // ^^^^^^^^^^^^^^^^^ expected struct `Meter`, found struct `Second`
To work around this, use unify()
, as follows:
use yaiouom::*; use yaiouom::si::*; let one_meter = Meter::new(1); let one_second = Second::new(1); let a = one_meter * one_second; let b = (one_second * one_meter).unify(); // Delays unit check. assert_eq!(a, b);
Soundness of unify
If you look at the signature of unify
, you can notice that
it returns a Measure<T, V>
for all V
. Despite appearances,
this is sound, for two reasons:
A refinement type for units of measure
The companion linter for this crate implements a refinement of
the Rust type system dedicated to units of measure. What this
means, in practice, is that whenever you call foo.unify()
,
it will check that the returned type is correct. By opposition
to the general Rust type system, it will correctly realize that
m * s
and s * m
are the same, or even that W * m / W
is
m
, even if Wß
is a type variable.
Please don't use unify()
without the linter :)
Dynamic checks
As a fallback, in debug builds, each call to unify
will panic
if type V
is not equivalent ot type U
.
pub fn from<V>(value: Measure<V, U>) -> Self where
T: From<V>,
[src]
T: From<V>,
Convert between two value representations (e.g. u32
vs u64
)
in the same unit.
Ideally, this should be an implementation of From
, but it conflicts
with the reflexive implementation.
use yaiouom::*; use yaiouom::si::*; let one_meter_usize = Meter::new(1 as i32); let one_meter_isize : Measure<i64, Meter> = Measure::from(one_meter_usize);
pub fn into<V>(self) -> Measure<V, U> where
T: Into<V>,
[src]
T: Into<V>,
Convert between two value representations (e.g. u32
vs u64
)
In the same unit.
Ideally, this should be an implementation of From
, but it conflicts
with the reflexive implementation.
use yaiouom::*; use yaiouom::si::*; let one_meter_usize : Measure<i32, Meter> = Measure::new(1); let one_meter_isize : Measure<i64, Meter> = one_meter_usize.into();
pub fn as_runtime(&self) -> RuntimeUnit
[src]
Extract a runtime representation of a unit.
This runtime representation is designed mainly for debugging purposes.
use yaiouom::*; use yaiouom::si::*; let one_meter_usize : Measure<i32, Meter> = Measure::new(1); assert_eq!(one_meter_usize.as_runtime().to_string(), "m");
Performance note
This method is fine for debugging, but should not be used in a tight loop.
impl<T, A: Unit> Measure<T, Mul<A, A>> where
T: Float,
[src]
T: Float,
impl<T> Measure<T, Dimensionless>
[src]
Trait Implementations
impl<T, U: Unit> Inv for Measure<T, U> where
T: Inv,
[src]
T: Inv,
type Output = Measure<T::Output, Inv<U>>
The result after applying the operator.
fn inv(self) -> Self::Output
[src]
Unary operator for retrieving the multiplicative inverse, or reciprocal, of a value.
impl<T, U: Unit> AsRef<T> for Measure<T, U>
[src]
impl<T, U: Unit> Clone for Measure<T, U> where
T: Clone,
[src]
T: Clone,
fn clone(&self) -> Self
[src]
Returns a copy of the value. Read more
fn clone_from(&mut self, source: &Self)
1.0.0[src]
Performs copy-assignment from source
. Read more
impl<T, U: Unit> Copy for Measure<T, U> where
T: Copy,
[src]
T: Copy,
impl<T, U: Unit> PartialEq for Measure<T, U> where
T: PartialEq,
[src]
T: PartialEq,
fn eq(&self, other: &Self) -> bool
[src]
This method tests for self
and other
values to be equal, and is used by ==
. Read more
fn ne(&self, other: &Rhs) -> bool
1.0.0[src]
This method tests for !=
.
impl<T, U: Unit> Eq for Measure<T, U> where
T: PartialEq,
[src]
T: PartialEq,
impl<T, U: Unit> PartialOrd for Measure<T, U> where
T: PartialOrd,
[src]
T: PartialOrd,
fn partial_cmp(&self, other: &Self) -> Option<Ordering>
[src]
This method returns an ordering between self
and other
values if one exists. Read more
fn lt(&self, other: &Rhs) -> bool
1.0.0[src]
This method tests less than (for self
and other
) and is used by the <
operator. Read more
fn le(&self, other: &Rhs) -> bool
1.0.0[src]
This method tests less than or equal to (for self
and other
) and is used by the <=
operator. Read more
fn gt(&self, other: &Rhs) -> bool
1.0.0[src]
This method tests greater than (for self
and other
) and is used by the >
operator. Read more
fn ge(&self, other: &Rhs) -> bool
1.0.0[src]
This method tests greater than or equal to (for self
and other
) and is used by the >=
operator. Read more
impl<T, U: Unit> Ord for Measure<T, U> where
T: Ord,
[src]
T: Ord,
fn cmp(&self, other: &Self) -> Ordering
[src]
This method returns an Ordering
between self
and other
. Read more
fn max(self, other: Self) -> Self
1.21.0[src]
Compares and returns the maximum of two values. Read more
fn min(self, other: Self) -> Self
1.21.0[src]
Compares and returns the minimum of two values. Read more
impl<T, U: Unit> Neg for Measure<T, U> where
T: Neg,
[src]
T: Neg,
type Output = Measure<T::Output, U>
The resulting type after applying the -
operator.
fn neg(self) -> Self::Output
[src]
Performs the unary -
operation.
impl<T, U: Unit> Zero for Measure<T, U> where
T: Zero,
[src]
T: Zero,
fn zero() -> Self
[src]
Returns the additive identity element of Self
, 0
. Read more
fn is_zero(&self) -> bool
[src]
Returns true
if self
is equal to the additive identity.
impl<T, U: Unit> Add<Self> for Measure<T, U> where
T: Add<Output = T>,
[src]
T: Add<Output = T>,
Out of the box, one may only add two values with the same unit.
It remains, however, possible to manually implement Add e.g. for a time and a duration or a point and a vector.
use yaiouom::*; use yaiouom::si::*; let one_meter : Measure<i32, Meter> = Measure::new(1); let two_meters = one_meter + one_meter; assert_eq!(*two_meters.as_ref(), 2);
type Output = Self
The resulting type after applying the +
operator.
fn add(self, rhs: Self) -> Self
[src]
Performs the +
operation.
impl<T, U: Unit> Mul<T> for Measure<T, U> where
T: Mul<T>,
[src]
T: Mul<T>,
type Output = Measure<<T as Mul>::Output, U>
The resulting type after applying the *
operator.
fn mul(self, rhs: T) -> Self::Output
[src]
Multiply a dimensionless value with a measure.
use yaiouom::*; use yaiouom::si::*; let one_meter : Measure<i32, Meter> = Measure::new(1); let ten_meters : Measure<i32, Meter> = one_meter * 10; assert_eq!(ten_meters.as_ref(), &10);
impl<T, U: Unit, V: Unit> Mul<Measure<T, V>> for Measure<T, U> where
T: Mul<T>,
[src]
T: Mul<T>,
type Output = Measure<<T as Mul>::Output, Mul<U, V>>
The resulting type after applying the *
operator.
fn mul(self, rhs: Measure<T, V>) -> Self::Output
[src]
Multiply two measures
use yaiouom::*; use yaiouom::si::*; let two_meters : Measure<i32, Meter> = Measure::new(2); let four_sq_meters : Measure<i32, Mul<Meter, Meter>> = two_meters * two_meters; assert_eq!(four_sq_meters.as_ref(), &4);
impl<T, U: Unit, V: Unit> Div<Measure<T, V>> for Measure<T, U> where
T: Div<T>,
[src]
T: Div<T>,
type Output = Measure<<T as Div>::Output, Mul<U, Inv<V>>>
The resulting type after applying the /
operator.
fn div(self, rhs: Measure<T, V>) -> Self::Output
[src]
Divide two measures
use yaiouom::*; use yaiouom::si::*; let four_sq_meters : Measure<i32, Mul<Meter, Meter>> = Measure::new(4); let two_meters : Measure<i32, Meter> = Measure::new(2); let other_two_meters : Measure<i32, _> = four_sq_meters / two_meters; assert_eq!(two_meters.as_ref(), other_two_meters.as_ref());
impl<T, U: Unit> Div<T> for Measure<T, U> where
T: Div<T>,
[src]
T: Div<T>,
type Output = Measure<<T as Div>::Output, U>
The resulting type after applying the /
operator.
fn div(self, rhs: T) -> Self::Output
[src]
Divide a dimensionless value by a measure.
use yaiouom::*; use yaiouom::si::*; let ten_meters : Measure<i32, Meter> = Measure::new(10); let one_meter : Measure<i32, Meter> = ten_meters / 10; assert_eq!(one_meter.as_ref(), &1);
impl<T, U: Unit> Sum for Measure<T, U> where
T: Sum,
[src]
T: Sum,
fn sum<I: Iterator<Item = Self>>(iter: I) -> Self
[src]
Method which takes an iterator and generates Self
from the elements by "summing up" the items. Read more
impl<T, U: Unit> Product for Measure<T, U> where
T: Product,
[src]
T: Product,
fn product<I: Iterator<Item = Self>>(iter: I) -> Self
[src]
Method which takes an iterator and generates Self
from the elements by multiplying the items. Read more
impl<T, U: Unit> Debug for Measure<T, U> where
T: Debug,
[src]
T: Debug,
fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error>
[src]
Formats the value using the given formatter. Read more