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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
//! Ferrunitas – Type‑safe physical quantities & units
//!
//! [](https://github.com/marekhummel/ferrunitas) 
//! [](https://crates.io/crates/ferrunitas) 
//! [](https://docs.rs/ferrunitas)
//!
//! 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`, `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 `Real`, either `f32` or `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.
// No standard library support
// Ignore precision warning when compilied with f32
// For String / format support
extern crate alloc;
// Define inner value type
compile_error!;
pub type Real = f64;
pub type Real = f32;
// 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;
/// Re-export typenum consts for easy access in macros
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;