[−][src]Struct phantom_newtype::Amount
Amount<Unit>
provides a type-safe way to keep an amount of
some Unit
.
E.g. the following code must not compile:
use phantom_newtype::Amount; // These structs are just markers and have no semantic meaning. enum Apples {} enum Oranges {} let trois_pommes = Amount::<Apples, u64>::from(3); let five_oranges = Amount::<Oranges, u64>::from(5); assert_eq!(8, (trois_pommes + five_oranges).get())
Amount<Unit, Repr>
defines common boilerplate to make type-safe
amounts more convenient. For example, you can compare amounts:
use phantom_newtype::Amount; enum Apples {} type NumApples = Amount<Apples, u64>; assert_eq!(true, NumApples::from(3) < NumApples::from(5)); assert_eq!(false, NumApples::from(3) > NumApples::from(5)); assert_eq!(true, NumApples::from(3) != NumApples::from(5)); assert_eq!(true, NumApples::from(5) == NumApples::from(5)); assert_eq!(false, NumApples::from(5) != NumApples::from(5)); assert_eq!(vec![NumApples::from(3), NumApples::from(5)].iter().max().unwrap(), &NumApples::from(5));
You can do simple arithmetics with amounts:
use phantom_newtype::Amount; enum Apples {} enum Oranges {} let x = Amount::<Apples, u64>::from(3); let y = Amount::<Oranges, u64>::from(5); assert_eq!(x + x, Amount::<Apples, u64>::from(6)); assert_eq!(y - y, Amount::<Oranges, u64>::from(0));
Multiplication of amounts is not supported: multiplying meters by meters gives square meters. However, you can scale an amount by a scalar or divide amounts:
use phantom_newtype::Amount; enum Apples {} let x = Amount::<Apples, u64>::from(3); assert_eq!(x * 3, Amount::<Apples, u64>::from(9)); assert_eq!(1, x / x); assert_eq!(3, (x * 3) / x);
Note that the unit is only available at compile time, thus using
Amount
instead of u64
doesn't incur any runtime penalty:
use phantom_newtype::Amount; enum Meters {} let ms = Amount::<Meters, u64>::from(10); assert_eq!(std::mem::size_of_val(&ms), std::mem::size_of::<u64>());
Amounts can be serialized and deserialized with serde
. Serialized
forms of Amount<Unit, Repr>
and Repr
are identical.
#[cfg(feature = "serde")] { use phantom_newtype::Amount; use serde::{Serialize, Deserialize}; use serde_json; enum Meters {} let repr: u64 = 10; let m_10 = Amount::<Meters, u64>::from(repr); assert_eq!(serde_json::to_string(&m_10).unwrap(), serde_json::to_string(&repr).unwrap()); let copy: Amount<Meters, u64> = serde_json::from_str(&serde_json::to_string(&m_10).unwrap()).unwrap(); assert_eq!(copy, m_10); }
You can also declare constants of Amount<Unit, Repr>
using new
function:
use phantom_newtype::Amount; enum Meters {} type Distance = Amount<Meters, u64>; const ASTRONOMICAL_UNIT: Distance = Distance::new(149_597_870_700); assert!(ASTRONOMICAL_UNIT > Distance::from(0));
Amounts can be sent between threads if the Repr
allows it, no
matter which Unit
is used.
use phantom_newtype::Amount; type Cell = std::cell::RefCell<i64>; type NumCells = Amount<Cell, i64>; const N: NumCells = NumCells::new(1); let n_from_thread = std::thread::spawn(|| &N).join().unwrap(); assert_eq!(N, *n_from_thread);
Methods
impl<Unit, Repr: Copy> Amount<Unit, Repr>
[src]
pub fn get(&self) -> Repr
[src]
Returns the wrapped value.
use phantom_newtype::Amount; enum Apples {} let three_apples = Amount::<Apples, u64>::from(3); assert_eq!(9, (three_apples * 3).get());
impl<Unit, Repr> Amount<Unit, Repr>
[src]
pub const fn new(repr: Repr) -> Amount<Unit, Repr>
[src]
new
is a synonym for from
that can be evaluated in
compile time. The main use-case of this functions is defining
constants.
impl<Unit: Default, Repr: Copy> Amount<Unit, Repr>
[src]
pub fn unit(&self) -> Unit
[src]
Provides a useful shortcut to access units of an amount if
they implement the Default
trait:
use phantom_newtype::Amount; #[derive(Debug, Default)] struct Seconds; let duration = Amount::<Seconds, u64>::from(5); assert_eq!("5 Seconds", format!("{} {:?}", duration, duration.unit()));
impl<Unit, Repr> Amount<Unit, Repr> where
Unit: DisplayerOf<Amount<Unit, Repr>>,
[src]
Unit: DisplayerOf<Amount<Unit, Repr>>,
pub fn display(&self) -> DisplayProxy<Self, Unit>
[src]
display
provides a machanism to implement a custom display
for phantom types.
use phantom_newtype::{Amount, DisplayerOf}; use std::fmt; struct Cents; type Money = Amount<Cents, u64>; impl DisplayerOf<Money> for Cents { fn display(amount: &Money, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "${}.{:02}", amount.get() / 100, amount.get() % 100) } } assert_eq!(format!("{}", Money::from(1005).display()), "$10.05");
Trait Implementations
impl<Unit, Repr: Copy> From<Repr> for Amount<Unit, Repr>
[src]
impl<Unit, Repr: Copy> Clone for Amount<Unit, Repr>
[src]
fn clone(&self) -> Self
[src]
fn clone_from(&mut self, source: &Self)
1.0.0[src]
impl<Unit, Repr: Copy> Copy for Amount<Unit, Repr>
[src]
impl<Unit, Repr: Eq> Eq for Amount<Unit, Repr>
[src]
impl<Unit, Repr: Ord> Ord for Amount<Unit, Repr>
[src]
fn cmp(&self, rhs: &Self) -> Ordering
[src]
fn max(self, other: Self) -> Self
1.21.0[src]
fn min(self, other: Self) -> Self
1.21.0[src]
fn clamp(self, min: Self, max: Self) -> Self
[src]
impl<Unit, Repr: PartialEq> PartialEq<Amount<Unit, Repr>> for Amount<Unit, Repr>
[src]
impl<Unit, Repr: PartialOrd> PartialOrd<Amount<Unit, Repr>> for Amount<Unit, Repr>
[src]
fn partial_cmp(&self, rhs: &Self) -> Option<Ordering>
[src]
#[must_use]
fn lt(&self, other: &Rhs) -> bool
1.0.0[src]
#[must_use]
fn le(&self, other: &Rhs) -> bool
1.0.0[src]
#[must_use]
fn gt(&self, other: &Rhs) -> bool
1.0.0[src]
#[must_use]
fn ge(&self, other: &Rhs) -> bool
1.0.0[src]
impl<Unit, Repr> Display for Amount<Unit, Repr> where
Repr: Display,
[src]
Repr: Display,
impl<Unit, Repr> Debug for Amount<Unit, Repr> where
Repr: Debug,
[src]
Repr: Debug,
impl<Unit, Repr> Div<Amount<Unit, Repr>> for Amount<Unit, Repr> where
Repr: Div<Repr> + Copy,
[src]
Repr: Div<Repr> + Copy,
type Output = <Repr as Div>::Output
The resulting type after applying the /
operator.
fn div(self, rhs: Self) -> Self::Output
[src]
impl<Unit, Repr> Sub<Amount<Unit, Repr>> for Amount<Unit, Repr> where
Repr: SubAssign + Copy,
[src]
Repr: SubAssign + Copy,
type Output = Self
The resulting type after applying the -
operator.
fn sub(self, rhs: Self) -> Self
[src]
impl<Unit, Repr, Repr2> Sub<Amount<Unit, Repr2>> for Instant<Unit, Repr> where
Repr: SubAssign<Repr2> + Copy,
Repr2: Copy,
[src]
Repr: SubAssign<Repr2> + Copy,
Repr2: Copy,
type Output = Self
The resulting type after applying the -
operator.
fn sub(self, rhs: Amount<Unit, Repr2>) -> Self
[src]
impl<Unit, Repr> Add<Amount<Unit, Repr>> for Amount<Unit, Repr> where
Repr: AddAssign + Copy,
[src]
Repr: AddAssign + Copy,
type Output = Self
The resulting type after applying the +
operator.
fn add(self, rhs: Self) -> Self
[src]
impl<Unit, Repr, Repr2> Add<Amount<Unit, Repr2>> for Instant<Unit, Repr> where
Repr: AddAssign<Repr2> + Copy,
Repr2: Copy,
[src]
Repr: AddAssign<Repr2> + Copy,
Repr2: Copy,
type Output = Self
The resulting type after applying the +
operator.
fn add(self, rhs: Amount<Unit, Repr2>) -> Self
[src]
impl<Unit, Repr> Mul<Repr> for Amount<Unit, Repr> where
Repr: MulAssign + Copy,
[src]
Repr: MulAssign + Copy,
type Output = Self
The resulting type after applying the *
operator.
fn mul(self, rhs: Repr) -> Self
[src]
impl<Unit, Repr> AddAssign<Amount<Unit, Repr>> for Amount<Unit, Repr> where
Repr: AddAssign + Copy,
[src]
Repr: AddAssign + Copy,
fn add_assign(&mut self, rhs: Self)
[src]
impl<Unit, Repr, Repr2> AddAssign<Amount<Unit, Repr2>> for Instant<Unit, Repr> where
Repr: AddAssign<Repr2> + Copy,
Repr2: Copy,
[src]
Repr: AddAssign<Repr2> + Copy,
Repr2: Copy,
fn add_assign(&mut self, rhs: Amount<Unit, Repr2>)
[src]
impl<Unit, Repr> SubAssign<Amount<Unit, Repr>> for Amount<Unit, Repr> where
Repr: SubAssign + Copy,
[src]
Repr: SubAssign + Copy,
fn sub_assign(&mut self, rhs: Self)
[src]
impl<Unit, Repr, Repr2> SubAssign<Amount<Unit, Repr2>> for Instant<Unit, Repr> where
Repr: SubAssign<Repr2> + Copy,
Repr2: Copy,
[src]
Repr: SubAssign<Repr2> + Copy,
Repr2: Copy,
fn sub_assign(&mut self, rhs: Amount<Unit, Repr2>)
[src]
impl<Unit, Repr> MulAssign<Repr> for Amount<Unit, Repr> where
Repr: MulAssign + Copy,
[src]
Repr: MulAssign + Copy,
fn mul_assign(&mut self, rhs: Repr)
[src]
impl<Unit, Repr: Hash> Hash for Amount<Unit, Repr>
[src]
fn hash<H: Hasher>(&self, state: &mut H)
[src]
fn hash_slice<H>(data: &[Self], state: &mut H) where
H: Hasher,
1.3.0[src]
H: Hasher,
impl<Unit, Repr: Serialize> Serialize for Amount<Unit, Repr>
[src]
impl<'de, Unit, Repr> Deserialize<'de> for Amount<Unit, Repr> where
Repr: Deserialize<'de>,
[src]
Repr: Deserialize<'de>,
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error>
[src]
Auto Trait Implementations
impl<Unit, Repr> Send for Amount<Unit, Repr> where
Repr: Send,
Unit: Send,
Repr: Send,
Unit: Send,
impl<Unit, Repr> Sync for Amount<Unit, Repr> where
Repr: Sync,
Unit: Send,
Repr: Sync,
Unit: Send,
impl<Unit, Repr> Unpin for Amount<Unit, Repr> where
Repr: Unpin,
Unit: Unpin,
Repr: Unpin,
Unit: Unpin,
impl<Unit, Repr> UnwindSafe for Amount<Unit, Repr> where
Repr: UnwindSafe,
Repr: UnwindSafe,
impl<Unit, Repr> RefUnwindSafe for Amount<Unit, Repr> where
Repr: RefUnwindSafe,
Repr: RefUnwindSafe,
Blanket Implementations
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<T> From<T> for T
[src]
impl<T> From<!> for T
[src]
impl<T> ToOwned for T where
T: Clone,
[src]
T: Clone,
type Owned = T
The resulting type after obtaining ownership.
fn to_owned(&self) -> T
[src]
fn clone_into(&self, target: &mut T)
[src]
impl<T> ToString for T where
T: Display + ?Sized,
[src]
T: Display + ?Sized,
impl<T, U> TryFrom<U> for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,
type Error = <U as TryFrom<T>>::Error
The type returned in the event of a conversion error.
fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>
[src]
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
fn borrow_mut(&mut self) -> &mut T
[src]
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,
impl<T> DeserializeOwned for T where
T: Deserialize<'de>,
[src]
T: Deserialize<'de>,