dimensional_quantity
Dimensional quantity: checking dimensions of physical quantities in compile time using generic const expressions
- This crate is experimental and uses unstable
generic_const_exprs
feature and can only be compiled with nightly toolchain. - If you need a stable solution, please check excellent dimensioned and uom crates.
- The only implemented underlying storage types are f64 and f32.
To use this crate, you need to enable generic_const_exprs
feature in your crate:
#![feature(generic_const_exprs)]
and build it with nightly by using cargo +nightly
:
or by adding rust-toolchain.toml
file with the following content to your project
[]
= "nightly"
and add this to your Cargo.toml
[]
= "0.0.1"
Here you will find:
-
Predefined dimensional quantities for International System of Units (SI).
-
Non-dimensional metric (kilo, micro, giga, etc.) and binary (Kibi, Mebi, ...) prefixes.
Examples
Creating dimensional quantities from f64
use ;
use ;
// This will create velocity of 10 m/s, default units are SI units
let v1: Velocity = new;
// This method is constant and works also at compile time:
const SPEED_OF_SOUND: Velocity = new;
// Various units of length are available at
// dimensional_quantity::si::extended::f64::units_of_measure::*
// Units are just constant dimensional quantities
// For example, MILLIMETER unit is defined as
// pub const MILLIMETER: Length = Length::new(1.0E-3);
// One way is using new_with_unit method:
let v2: Velocity = new_with_unit;
// Another is just multiplying f64 with unit:
let v3: Velocity = 10_000.0 * MILLIMETER_PER_SECOND;
// Any of the above methods lead to the same result:
assert_eq!;
assert_eq!;
Converting dimensional quantities back to f64
use ;
use ;
// Getting f64 value of dimensional quantity in SI units:
// Velocity of 10 m/s
let v1: Velocity = new;
// Velocity of 343 m/s
const SPEED_OF_SOUND: Velocity = new;
let v1_value_is_si_units = v1.get_with_si_unit;
// also possible at compile time:
const SPEED_OF_SOUND_IN_SI_UNITS:f64 = SPEED_OF_SOUND.get_with_si_unit;
assert_eq!;
assert_eq!;
// Getting f64 value of dimensional quantity in arbitrary units is possible:
let v1_value_is_mm_per_second = v1.get_with_unit;
assert_eq!;
Mathematical operations with dimensional quantities
use ;
use ;
use ;
use PI;
let width: Length = 5.0 * METER;
let height: Length = 8.0 * METER;
// Quantities can be multiplied or divided by f64 floating numbers,
// resulting in quantities of same dimension
let double_height: Length = height * 2.0;
let half_width = width / 2.0;
assert_eq!;
assert_eq!;
// Dividing f64 by dimensional quantity returns reciprocal quantity:
let red_light_wavelength: Length = 0.65 * MICROMETER;
let red_light_k: ReciprocalLength = 2.0 * PI / red_light_wavelength;
let red_light_k_in_reciprocal_cm = red_light_k.get_with_unit;
assert_eq!;
// Most quantities of same dimension (except ones containing ThermodynamicTemperatures,
// that will be discussed below) can be added or subtracted:
let perimeter: Length = 2.0 * ;
// AddAssign and SubAssign operators are supported
let mut width_minus_height = new;
width_minus_height += width;
width_minus_height -= height;
assert_eq!;
// Dimensional quantities can be multiplied and divided:
let area_1: Area = width * height;
let area_2: Area = half_width * double_height;
assert_eq!;
let height_1 :Length = area_1 / width;
assert_eq!;
// Dimensional quantities can also be raised to an integer power during compile time
let v: Velocity = new;
let m: Mass = new; // 5 kg
let e: Energy = m * v. / 2.0;
assert_eq!;
Attempting to add, subtract, or assign quantities with mismatching dimensions will results in compile-time error:
#![feature(generic_const_exprs)]
use dimensional_quantity::si::extended::{Area, Length};
let length: Length = Length::new(10.0);
let area: Area = length.powi<2>();
// Type mismatch: can not add Length and Area:
let fail_1 = length + area;
// Type mismatch: can not subtract Area from Length:
let fail_2 = length - area;
// Type mismatch: can not assign Area to Length:
let fail_3: Length = area;
Creating new quantities and tests
If some quantity or unit are not implemented in predefined dimensional quantities and predefined units of measure, then new quantity and units can be defined:
use ;
use Quantity;
// New quantity: amount of information per unit of volume, standard unit of measure: Bit per cubic meter, B ⋅ m<sup>-3</sup>:
pub type VolumetricInformationDensity = 3, // Length
0, // Mass
0, // Time
0, // ElectricCurrent
0, // ThermodynamicTemperature
0, // AmountOfSubstance
0, // LuminousIntensity
0, // TemperatureInterval
0, // Angle
1, // Information
>;
pub const GIGABIT_PER_CUBIC_METER: VolumetricInformationDensity = new;
let information_density_1: VolumetricInformationDensity = 5.0 * GIGABIT_PER_CUBIC_METER;
let information_density_2: VolumetricInformationDensity = new / new;
assert_eq!;
Definition of quantities and units of measure
Quantities and corresponding units are defined at src/si/quantities_definition/*toml
files.
For example, definition of Area quantity is:
= "Area"
= "Area"
= "area"
= "L<sup>2</sup>"
= "Length<sup>2</sup>"
= "m<sup>2</sup>"
[]
= 2
= 0
= 0
= 0
= 0
= 0
= 0
= 0
= 0
= 0
[]
= "1.0E0"
= "m²"
= "square meter"
= "square meters"
[]
= "1.0_E-4"
= "cm²"
= "square centimeter"
= "square centimeters"
Licence
Licensed under either of Apache License, Version 2.0 or MIT license (LICENSE-MIT or https://opensource.org/licenses/MIT) at your option.
License: MIT OR Apache-2.0