Skip to main content

DynQuantity

Struct DynQuantity 

Source
#[repr(C)]
pub struct DynQuantity<V>{ pub value: V, pub unit: Unit, }
Expand description

This type represents a physical quantity via its numerical value and a unit of measurement (field exponents). The unit of measurement is not defined via the type system, but rather via the values of the Unit. This means that the unit of measurement is not fixed at compile time, but can change dynamically at runtime.

This property is very useful when e.g. parsing a user-provided string to a physical quantity. For this case, DynQuantity implements the FromStr trait. The module documentation from_str has more information regarding the available syntax.

The V generic parameter needs to implement F64RealOrComplex. Currently, implementors are f64 and Complex<f64>. It is possible to convert between those two types using the methods provided by F64RealOrComplex. In general, you likely want V to be f64 except when dealing with complex quantities such as alternating currents.

This struct can also be pretty-print the quantity it represents via its std::fmt::Display implementation:

use std::str::FromStr;
use dyn_quantity::DynQuantity;

let quantity = DynQuantity::<f64>::from_str("9.81 m/s^2").expect("parseable");
assert_eq!(quantity.to_string(), "9.81 s^-2 m".to_string());

§Conversion into uom Quantity

If the uom feature is enabled, a DynQuantity can be (fallible) converted into a Quantity via TryFrom. In combination with the aforementioned parsing capabilities, this allows fallible parsing of strings to statically-typed physical quantities.

§Serialization and deserialization

If the serde feature is enabled, this struct can be serialized and deserialized. Serialization creates the “standard” serde representation one would expect from the Serialize macro.

When deserializing however, multiple options are available:

  1. Using the “standard” serialized representation of a struct. For example, the yaml representation of a DynQuantity<f64> looks like this:
---
value: 2.0
exponents:
    second: 0
    meter: 1
    kilogram: 0
    ampere: 1
    kelvin: 0
    mol: 0
    candela: 0
  1. Deserializing directly from a string. This uses the std::str::FromStr implementation under the hood, see the from_str module documentation. Only available if the from_str feature is enabled.
  2. Deserialize directly from a real or complex value. This option is mainly here to allow deserializing a serialized uom quantity (whose serialized representation is simply its numerical value without any units). For example, deserializing 5.0 into DynQuantity<f64> produces the same result as deserializing:
---
value: 5.0
exponents:
    second: 0
    meter: 0
    kilogram: 0
    ampere: 0
    kelvin: 0
    mol: 0
    candela: 0

The three different possibilities are realized via a crate-internal untagged enum.

Fields§

§value: V

The value of the physical quantity.

§unit: Unit

The (SI) base units of the physical quantity, represented by their exponents.

Implementations§

Source§

impl<V> DynQuantity<V>

Source

pub fn new<U>(value: V, unit: U) -> DynQuantity<V>
where U: Into<Unit>,

Returns a new instance of Self.

Source

pub fn try_add( &self, other: &DynQuantity<V>, ) -> Result<DynQuantity<V>, UnitsNotEqual>

Fallible addition of self and other.

Physical quantities can only be added together if their units are identical. Hence, this function first compares the .unit fields of self and other. If they are identical, the value fields are added up and the resulting quantity is returned. Otherwise, a UnitsNotEqual error is returned.

§Examples
use std::str::FromStr;
use dyn_quantity::DynQuantity;

let curr1 = DynQuantity::<f64>::from_str("1 A").expect("valid");
let curr2 = DynQuantity::<f64>::from_str("1 V*A / V").expect("valid");
let volt1 = DynQuantity::<f64>::from_str("-5 V").expect("valid");

// The currents can be added ...
let curr_sum = curr1.try_add(&curr2).expect("can be added");
assert_eq!(curr_sum.value, 2.0);
assert_eq!(curr_sum.unit.ampere, 1);

// ... but adding a current to a voltage fails.
assert!(volt1.try_add(&curr1).is_err());
Source

pub fn try_add_assign( &mut self, other: &DynQuantity<V>, ) -> Result<(), UnitsNotEqual>

Like DynQuantity::try_add, but assigns the sum of self and other to self instead of returning it. If the addition fails, self is not modified.

§Examples
use std::str::FromStr;
use dyn_quantity::DynQuantity;

let mut curr1 = DynQuantity::<f64>::from_str("1 A").expect("valid");
let curr2 = DynQuantity::<f64>::from_str("1 V*A / V").expect("valid");
let mut volt1 = DynQuantity::<f64>::from_str("-5 V").expect("valid");

// curr1 gets overwritten
curr1.try_add_assign(&curr2).expect("can be added");
assert_eq!(curr1.value, 2.0);
assert_eq!(curr1.unit.ampere, 1);

// volt1 does not get modified because the addition failed
let volt_cpy = volt1.clone();
assert!(volt1.try_add_assign(&curr1).is_err());
assert_eq!(volt1, volt_cpy);
Source

pub fn try_sub( &self, other: &DynQuantity<V>, ) -> Result<DynQuantity<V>, UnitsNotEqual>

Fallible subtraction of self and other.

Physical quantities can only be subtracted from each other if their units are identical. Hence, this function first compares the .unit fields of self and other. If they are identical, the value fields are subtracted up and the resulting quantity is returned. Otherwise, a UnitsNotEqual error is returned.

§Examples
use std::str::FromStr;
use dyn_quantity::DynQuantity;

let curr1 = DynQuantity::<f64>::from_str("1 A").expect("valid");
let curr2 = DynQuantity::<f64>::from_str("1 V*A / V").expect("valid");
let volt1 = DynQuantity::<f64>::from_str("-5 V").expect("valid");

// The currents can be subtracted ...
let curr_sum = curr1.try_sub(&curr2).expect("can be added");
assert_eq!(curr_sum.value, 0.0);
assert_eq!(curr_sum.unit.ampere, 1);

// ... but sbutracting a current from a voltage fails.
assert!(volt1.try_sub(&curr1).is_err());
Source

pub fn try_sub_assign( &mut self, other: &DynQuantity<V>, ) -> Result<(), UnitsNotEqual>

Like DynQuantity::try_sub, but assigns the difference of self and other to self instead of returning it. If the subtraction fails, self is not modified.

§Examples
use std::str::FromStr;
use dyn_quantity::DynQuantity;

let mut curr1 = DynQuantity::<f64>::from_str("1 A").expect("valid");
let curr2 = DynQuantity::<f64>::from_str("1 V*A / V").expect("valid");
let mut volt1 = DynQuantity::<f64>::from_str("-5 V").expect("valid");

// curr1 gets overwritten
curr1.try_sub_assign(&curr2).expect("can be added");
assert_eq!(curr1.value, 0.0);
assert_eq!(curr1.unit.ampere, 1);

// volt1 does not get modified because the addition failed
let volt_cpy = volt1.clone();
assert!(volt1.try_sub_assign(&curr1).is_err());
assert_eq!(volt1, volt_cpy);
Source

pub fn powi(self, n: i32) -> DynQuantity<V>

Raises self to an integer power.

§Examples
use std::str::FromStr;
use dyn_quantity::DynQuantity;

let curr = DynQuantity::<f64>::from_str("2 A^2").expect("valid");
let result = curr.powi(3);
assert_eq!(result.value, 8.0);
assert_eq!(result.unit.ampere, 6);
Source

pub fn try_nthroot(self, n: i32) -> Result<DynQuantity<V>, RootError>

Tries to calculate the nth root of self.

Trait Implementations§

Source§

impl<V> Clone for DynQuantity<V>

Source§

fn clone(&self) -> DynQuantity<V>

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<V> Debug for DynQuantity<V>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl<V> Default for DynQuantity<V>

Source§

fn default() -> DynQuantity<V>

Returns the “default value” for a type. Read more
Source§

impl<'de, V> Deserialize<'de> for DynQuantity<V>
where V: F64RealOrComplex + Deserialize<'de>,

Source§

fn deserialize<D>( deserializer: D, ) -> Result<DynQuantity<V>, <D as Deserializer<'de>>::Error>
where D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl<V> Display for DynQuantity<V>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl<V> Div<f64> for DynQuantity<V>

Source§

type Output = DynQuantity<V>

The resulting type after applying the / operator.
Source§

fn div(self, rhs: f64) -> <DynQuantity<V> as Div<f64>>::Output

Performs the / operation. Read more
Source§

impl<V> Div for DynQuantity<V>

Source§

type Output = DynQuantity<V>

The resulting type after applying the / operator.
Source§

fn div(self, rhs: DynQuantity<V>) -> <DynQuantity<V> as Div>::Output

Performs the / operation. Read more
Source§

impl<V> DivAssign<f64> for DynQuantity<V>

Source§

fn div_assign(&mut self, rhs: f64)

Performs the /= operation. Read more
Source§

impl<V> DivAssign for DynQuantity<V>

Source§

fn div_assign(&mut self, rhs: DynQuantity<V>)

Performs the /= operation. Read more
Source§

impl From<Complex<f64>> for DynQuantity<Complex<f64>>

Source§

fn from(value: Complex<f64>) -> DynQuantity<Complex<f64>>

Converts to this type from the input type.
Source§

impl From<DynQuantity<f64>> for DynQuantity<Complex<f64>>

Source§

fn from(value: DynQuantity<f64>) -> DynQuantity<Complex<f64>>

Converts to this type from the input type.
Source§

impl From<Operation> for DynQuantity<Complex<f64>>

Source§

fn from(value: Operation) -> DynQuantity<Complex<f64>>

Converts to this type from the input type.
Source§

impl<L, M, T, I, Th, N, J, K, V> From<Quantity<dyn Dimension<Kind = K, J = J, L = L, Th = Th, M = M, I = I, T = T, N = N>, dyn Units<f64, length = meter, luminous_intensity = candela, amount_of_substance = mole, time = second, mass = kilogram, electric_current = ampere, thermodynamic_temperature = kelvin>, f64>> for DynQuantity<V>
where L: Integer, M: Integer, T: Integer, I: Integer, Th: Integer, N: Integer, J: Integer, V: F64RealOrComplex, K: ?Sized,

Source§

fn from( quantitiy: Quantity<dyn Dimension<Kind = K, J = J, L = L, Th = Th, M = M, I = I, T = T, N = N>, dyn Units<f64, length = meter, luminous_intensity = candela, amount_of_substance = mole, time = second, mass = kilogram, electric_current = ampere, thermodynamic_temperature = kelvin>, f64>, ) -> DynQuantity<V>

Converts to this type from the input type.
Source§

impl From<f64> for DynQuantity<f64>

Source§

fn from(value: f64) -> DynQuantity<f64>

Converts to this type from the input type.
Source§

impl<V> FromStr for DynQuantity<V>

Source§

type Err = ParseError

The associated error which can be returned from parsing.
Source§

fn from_str(s: &str) -> Result<DynQuantity<V>, <DynQuantity<V> as FromStr>::Err>

Parses a string s to return a value of this type. Read more
Source§

impl<V> Mul<f64> for DynQuantity<V>

Source§

type Output = DynQuantity<V>

The resulting type after applying the * operator.
Source§

fn mul(self, rhs: f64) -> <DynQuantity<V> as Mul<f64>>::Output

Performs the * operation. Read more
Source§

impl<V> Mul for DynQuantity<V>

Source§

type Output = DynQuantity<V>

The resulting type after applying the * operator.
Source§

fn mul(self, rhs: DynQuantity<V>) -> <DynQuantity<V> as Mul>::Output

Performs the * operation. Read more
Source§

impl<V> MulAssign<f64> for DynQuantity<V>

Source§

fn mul_assign(&mut self, rhs: f64)

Performs the *= operation. Read more
Source§

impl<V> MulAssign for DynQuantity<V>

Source§

fn mul_assign(&mut self, rhs: DynQuantity<V>)

Performs the *= operation. Read more
Source§

impl<V> PartialEq for DynQuantity<V>

Source§

fn eq(&self, other: &DynQuantity<V>) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl<V> Serialize for DynQuantity<V>

Source§

fn serialize<S>( &self, serializer: S, ) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
where S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl TryFrom<DynQuantity<Complex<f64>>> for Complex<f64>

Source§

type Error = ConversionError

The type returned in the event of a conversion error.
Source§

fn try_from( quantity: DynQuantity<Complex<f64>>, ) -> Result<Complex<f64>, <Complex<f64> as TryFrom<DynQuantity<Complex<f64>>>>::Error>

Performs the conversion.
Source§

impl TryFrom<DynQuantity<Complex<f64>>> for DynQuantity<f64>

Source§

type Error = NotConvertibleFromComplexF64

The type returned in the event of a conversion error.
Source§

fn try_from( quantity: DynQuantity<Complex<f64>>, ) -> Result<DynQuantity<f64>, <DynQuantity<f64> as TryFrom<DynQuantity<Complex<f64>>>>::Error>

Performs the conversion.
Source§

impl TryFrom<DynQuantity<Complex<f64>>> for f64

Source§

type Error = ConversionError

The type returned in the event of a conversion error.
Source§

fn try_from( quantity: DynQuantity<Complex<f64>>, ) -> Result<f64, <f64 as TryFrom<DynQuantity<Complex<f64>>>>::Error>

Performs the conversion.
Source§

impl<L, M, T, I, Th, N, J, K, V> TryFrom<DynQuantity<V>> for Quantity<dyn Dimension<Kind = K, J = J, L = L, Th = Th, M = M, I = I, T = T, N = N>, dyn Units<Complex<f64>, length = meter, luminous_intensity = candela, amount_of_substance = mole, time = second, mass = kilogram, electric_current = ampere, thermodynamic_temperature = kelvin>, Complex<f64>>
where L: Integer, M: Integer, T: Integer, I: Integer, Th: Integer, N: Integer, J: Integer, V: F64RealOrComplex, K: ?Sized,

Source§

type Error = ConversionError

The type returned in the event of a conversion error.
Source§

fn try_from( quantity: DynQuantity<V>, ) -> Result<Quantity<dyn Dimension<Kind = K, J = J, L = L, Th = Th, M = M, I = I, T = T, N = N>, dyn Units<Complex<f64>, length = meter, luminous_intensity = candela, amount_of_substance = mole, time = second, mass = kilogram, electric_current = ampere, thermodynamic_temperature = kelvin>, Complex<f64>>, <Quantity<dyn Dimension<Kind = K, J = J, L = L, Th = Th, M = M, I = I, T = T, N = N>, dyn Units<Complex<f64>, length = meter, luminous_intensity = candela, amount_of_substance = mole, time = second, mass = kilogram, electric_current = ampere, thermodynamic_temperature = kelvin>, Complex<f64>> as TryFrom<DynQuantity<V>>>::Error>

Performs the conversion.
Source§

impl<L, M, T, I, Th, N, J, K, V> TryFrom<DynQuantity<V>> for Quantity<dyn Dimension<Kind = K, J = J, L = L, Th = Th, M = M, I = I, T = T, N = N>, dyn Units<f64, length = meter, luminous_intensity = candela, amount_of_substance = mole, time = second, mass = kilogram, electric_current = ampere, thermodynamic_temperature = kelvin>, f64>
where L: Integer, M: Integer, T: Integer, I: Integer, Th: Integer, N: Integer, J: Integer, V: F64RealOrComplex, K: ?Sized,

Source§

type Error = ConversionError

The type returned in the event of a conversion error.
Source§

fn try_from( quantity: DynQuantity<V>, ) -> Result<Quantity<dyn Dimension<Kind = K, J = J, L = L, Th = Th, M = M, I = I, T = T, N = N>, dyn Units<f64, length = meter, luminous_intensity = candela, amount_of_substance = mole, time = second, mass = kilogram, electric_current = ampere, thermodynamic_temperature = kelvin>, f64>, <Quantity<dyn Dimension<Kind = K, J = J, L = L, Th = Th, M = M, I = I, T = T, N = N>, dyn Units<f64, length = meter, luminous_intensity = candela, amount_of_substance = mole, time = second, mass = kilogram, electric_current = ampere, thermodynamic_temperature = kelvin>, f64> as TryFrom<DynQuantity<V>>>::Error>

Performs the conversion.
Source§

impl TryFrom<DynQuantity<f64>> for Complex<f64>

Source§

type Error = ConversionError

The type returned in the event of a conversion error.
Source§

fn try_from( quantity: DynQuantity<f64>, ) -> Result<Complex<f64>, <Complex<f64> as TryFrom<DynQuantity<f64>>>::Error>

Performs the conversion.
Source§

impl TryFrom<DynQuantity<f64>> for f64

Source§

type Error = ConversionError

The type returned in the event of a conversion error.
Source§

fn try_from( quantity: DynQuantity<f64>, ) -> Result<f64, <f64 as TryFrom<DynQuantity<f64>>>::Error>

Performs the conversion.
Source§

impl<L, M, T, I, Th, N, J, K, V> TryFrom<Quantity<dyn Dimension<Kind = K, J = J, L = L, Th = Th, M = M, I = I, T = T, N = N>, dyn Units<Complex<f64>, length = meter, luminous_intensity = candela, amount_of_substance = mole, time = second, mass = kilogram, electric_current = ampere, thermodynamic_temperature = kelvin>, Complex<f64>>> for DynQuantity<V>
where L: Integer, M: Integer, T: Integer, I: Integer, Th: Integer, N: Integer, J: Integer, V: F64RealOrComplex, K: ?Sized,

Source§

type Error = NotConvertibleFromComplexF64

The type returned in the event of a conversion error.
Source§

fn try_from( quantitiy: Quantity<dyn Dimension<Kind = K, J = J, L = L, Th = Th, M = M, I = I, T = T, N = N>, dyn Units<Complex<f64>, length = meter, luminous_intensity = candela, amount_of_substance = mole, time = second, mass = kilogram, electric_current = ampere, thermodynamic_temperature = kelvin>, Complex<f64>>, ) -> Result<DynQuantity<V>, <DynQuantity<V> as TryFrom<Quantity<dyn Dimension<Kind = K, J = J, L = L, Th = Th, M = M, I = I, T = T, N = N>, dyn Units<Complex<f64>, length = meter, luminous_intensity = candela, amount_of_substance = mole, time = second, mass = kilogram, electric_current = ampere, thermodynamic_temperature = kelvin>, Complex<f64>>>>::Error>

Performs the conversion.
Source§

impl<V> TryFrom<QuantityVariants<V>> for DynQuantity<V>

Source§

type Error = ParseError

The type returned in the event of a conversion error.
Source§

fn try_from( variant: QuantityVariants<V>, ) -> Result<DynQuantity<V>, <DynQuantity<V> as TryFrom<QuantityVariants<V>>>::Error>

Performs the conversion.
Source§

impl<V> Copy for DynQuantity<V>

Source§

impl<V> StructuralPartialEq for DynQuantity<V>

Auto Trait Implementations§

§

impl<V> Freeze for DynQuantity<V>
where V: Freeze,

§

impl<V> RefUnwindSafe for DynQuantity<V>
where V: RefUnwindSafe,

§

impl<V> Send for DynQuantity<V>
where V: Send,

§

impl<V> Sync for DynQuantity<V>
where V: Sync,

§

impl<V> Unpin for DynQuantity<V>
where V: Unpin,

§

impl<V> UnsafeUnpin for DynQuantity<V>
where V: UnsafeUnpin,

§

impl<V> UnwindSafe for DynQuantity<V>
where V: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DynClone for T
where T: Clone,

Source§

fn __clone_box(&self, _: Private) -> *mut ()

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> Serialize for T
where T: Serialize + ?Sized,

Source§

fn erased_serialize(&self, serializer: &mut dyn Serializer) -> Result<(), Error>

Source§

fn do_erased_serialize( &self, serializer: &mut dyn Serializer, ) -> Result<(), ErrorImpl>

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

Source§

impl<T> SendAlias for T

Source§

impl<T> SyncAlias for T