Expand description
Ferrunitas – Type‑safe physical quantities & units
Ferrunitas lets you express physical formulas with compile‑time dimensional
analysis. Using incompatible units results in a compile error
instead of a runtime surprise. Values are stored as raw Real, while types
encode the dimensional signature (mass, length, time, …) via the type system.
§Goals
- Zero / near‑zero runtime overhead (all dimension checks at compile time)
- Ergonomic construction & conversion of units (e.g.
Kilogram::new(5.0)) - Seamless arithmetic on both concrete units (e.g.
Newton) and generic quantities (e.g.Force) - Prefix & compound unit support (kilo, milli, square, per, etc.)
- Optional quantity tagging to distinguish semantically different but dimensionally identical quantities
§Core Concepts
- Unit type: A concrete label like
Kilogram,Metre,Newtonthat carries its dimensional vector & scaling factor to an internal base. - Quantity: A dimensioned numeric value without a fixed display unit.
You obtain a quantity via
some_unit.into_q()and it will be the result of multiplication and division. They work best when converted back to measures and as types for methods. - Quantity Tags (optional): When the
quantity_tagsfeature is enabled, quantities can carry additional type information to distinguish between dimensionally identical but semantically different values (e.g.,AnglevsInformation). - Prefixes / Compounds: Generated via macros (e.g.
Millivolt,SquareMetre,MetrePerSecond). These are normal unit types. - Conversion: Convert a quantity back to a chosen unit type with
quantity.as_measure::<TargetUnit>()or convert between unit types by going through a quantity:let kg: Kilogram = grams.convert();.
§Quick Start
use ferrunitas::{system::*, Measure, Unit};
// Construct concrete units
let m = 5 * Kilogram; // 5 kg
let a = MetrePerSecondSquared::new(2.0); // 2 m/s²
// Multiply → force (unit × unit -> compound quantity)
let f_q = m * a + Millinewton::new(20.0); // A quantity of type Force
let f: Measure<Newton> = f_q.as_measure(); // Represent it as Newtons
assert_eq!(f.value(), 10.02);
// Unit ↔ Quantity ↔ Unit conversion
let g = Gram::new(5000.0); // 5000 g
let kg_again = g.convert::<Kilogram>();
assert_eq!(kg_again.value(), 5.0);§Relevant imports
// For access to all definitions to units, quantities and prefixes
use ferrunitas::system::*;
// Crate root access to most common struct Measure and trait Unit to make methods available
use ferrunitas::{Measure, Unit};
// For dimensional formatting
use ferrunitas::common::{format_dims, format_unit_dims};
// Macros for own definitions (typenum consts for quantity macro)
use ferrunitas::typenum_consts::*;
use ferrunitas::{prefix, quantity, unit};§Limitations / Notes
- Internal storage uses
Real, eitherf32orf64; typical floating point caveats apply, see examples/misc.rs. - Rounding / formatting of display values is a caller concern, usual format specifiers are respected.
- Offsets are supported for temperature scales, but are quite limited in usage besides simple conversion.
§Extending
New units, prefixes, or compound relationships can be created using
the provided macros (unit!, etc.). The results work just like all the
predefined macros.
Modules§
- common
- Common helper functions & utilities shared across units / quantities. Common helpers & internal testing utilities.
- system
- Public system definitions: base, derived, prefixed, and compound units. Public unit system namespace.
- typenum_
consts - Re-export typenum consts for easy access in macros
Macros§
- prefix
- Macro to define a prefix with its factor, symbol, and name
- quantity
- Define a new quantity either by a list of 7 dimensions or by compounding others.
- unit
- Macro to define a new unit
Structs§
- Measure
- Runtime holder of a numeric value tagged with a concrete unit type
U.
Traits§
- Unit
- Core trait implemented by every concrete unit type.