1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
//! 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 `f64`, 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`, `Newton` that
//! 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_tags` feature is enabled,
//! quantities can carry additional type information to distinguish between
//! dimensionally identical but semantically different values (e.g., `Angle` vs `Information`).
//! * **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
//! ```rust
//! 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
//! ```rust
//! // 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 `f64`; 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.
// Make all definitions and the common functions public
/// Common helper functions & utilities shared across units / quantities.
/// Public system definitions: base, derived, prefixed, and compound units.
// Keep model internal, but re-export some types for the exported macros
// Export some modules / types on crate level for easy access
pub use crateMeasure;
pub use crateUnit;
pub use consts as typenum_consts;
// For manual testing, this may be used (keeps compiler overhead low)
// pub mod system_test;
// pub use crate::system_test as system;