Expand description
§danwi
A zero-cost dimensional analysis library for Rust with SI units, compile-time
type checking, and no_std support.
§Usage
use danwi::prelude::*;
// dimensions combine at the type level; mismatches are compile errors
let v = 5.0.mA() * 2.0.kOhm();
assert_eq!(v, 10.0.V());
// convert and format in any unit of the same dimension
assert_eq!(v.to(mV), 10000.0);
println!("{}", v.display_as(mV)); // 10000 mV
// values are stored in SI base units, so mixed prefixes just work
let len = 100.0.m() + 50.0 * cm + 0.001 * km;
assert_eq!(len.value(), 101.5);
// non-SI units: minute, hour, Celsius, litre, inch, ...
let temp = 25.0.celsius();
assert_eq!(temp.to(K), 298.15);
println!("{}", temp.display_as(degC)); // 25 °CCustom units are one line each; the built-in set is itself a single
units! invocation:
mod imperial {
danwi::units! {
mile: danwi::dimension::Length { symbol: mi, scale: 1_609_344 / 1_000 },
}
}
use danwi::prelude::*;
use imperial::ext::F64QuantityExt as _;
assert_eq!(1.0.mile(), 1609.344.m());Some quantities share a dimension but mean different things: torque and
energy are both M·L²·T⁻². Kinds keep them apart. Every quantity has an
invisible default kind, so nothing changes until you opt in with
cast_kind; a named kind only adds and compares with itself, and must be
erased explicitly before multiplying:
use danwi::{kind::Torque, prelude::*};
let torque = (50.0.N() * 0.4.m()).cast_kind::<Torque>();
assert_eq!(torque + torque, (40.0.J()).cast_kind());
// torque + 5.0.J() does not compile; neither does torque / 2.0.s()
assert_eq!(torque.erase_kind(), 20.0.J());Custom kinds are one line: danwi::kinds! { Activity; }.
§Getting started
[dependencies]
danwi = "0.4"The default scalar type is f64. For f32, enable the feature:
danwi = { version = "0.4", features = ["f32"] } # both
danwi = { version = "0.4", default-features = false, features = ["f32"] } # f32 onlyImport the prelude and go:
use danwi::prelude::*;
let i = 12.0.V() / 4.0.kOhm();
assert_eq!(i, 3.0.mA());With both scalar features enabled, an unsuffixed literal in value * unit
syntax can be ambiguous (write 10.0_f64 * V); the extension methods
(10.0.V()) never are.
Construction and conversion compile to at most one float op each, and
everything in between is plain scalar arithmetic; verify with
cargo rustc --release --example asm_check -- --emit=asm.
Re-exports§
pub use quantity::Quantity;pub use quantity::UnitDisplay;pub use quantity::kind;pub use scalar::Scalar;pub use unit::Unit;pub use unit::UnitDef;pub use unit::si::ext::F32QuantityExt;pub use unit::si::ext::F64QuantityExt;
Modules§
- compile_
checks - Things that fail to compile.
- dimension
- Type-level dimensions with compile-time arithmetics.
- f32
f32quantities: the extension trait (asQuantityExt), unitconstants, andtypesaliases.- f64
f64quantities: the extension trait (asQuantityExt), unitconstants, andtypesaliases.- prelude
- Glob import for
f64users: the extension trait, all unit constants, and allQuantitytype aliases. - quantity
Quantity, a scalar tagged with a compile-time dimension.- scalar
- Scalar numeric types usable as the value of a
Quantity. - unit
- Units as zero-sized marker types.