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
134
135
136
137
138
139
140
141
142
143
144
145
146
//! A library providing type safety and ergonomics for working with units of
//! measurement, based on the [newtype] pattern.
//!
//! At the core of this library is the [`Unit`] trait defining the behavior
//! of a unit of measurement, based on the principle that an agreed base unit
//! exists with which from/ to conversions can be made to obtain any given unit.
//!
//! Along with the [`Unit`] trait, multiple other traits are provided which
//! represent individual measurable quantities (e.g. [`length::Length`],
//! [`mass::Mass`]). These traits provide additional semantics that allow
//! correct ant automatic inter-usability of units of the same quantity and
//! protect against inadvertent use of incorrect units at compile time. In
//! addition, these quantity traits provide useful and valid mathematical
//! operations between the units.
//!
//! For each provided quantity trait the library provides their common units
//! (e.g. [`mass::metric::Gram`], [`mass::imperial::Pound`]) and, for the metric
//! units, their multiples (e.g. [`length::metric::KiloMeter`],
//! [`length::metric::MilliMeter`]).
//!
//! In case you didn't find a unit that you need, you can implement the [`Unit`]
//! and the desired quantity trait yourself, or you can use the derive macros
//! from the [`derive`] module (see examples below).
//!
//! If you believe a unit or a quantity is missing, feel free to open an issue
//! or a PR!
//!
//! # Examples
//!
//! Use the predefined units:
//!
//! ```
//! use newnit::length::imperial::Foot;
//! use newnit::substance_amount::metric::KiloMole;
//!
//! let length = Foot(32.0);
//! let oxygen_amount = KiloMole(4.0);
//! ```
//!
//! Get the base representation of a unit:
//!
//! ```
//! use newnit::Unit;
//! use newnit::mass::Mass;
//! use newnit::mass::imperial::Ounce;
//!
//! fn display_weight(weight: &dyn Mass) {
//! println!("Weight in kilograms is: {}", weight.to_base());
//! }
//!
//! fn main() {
//! let weight_in_ounces = Ounce(4.0);
//! display_weight(&weight_in_ounces);
//! }
//! ```
//!
//! Seamlessly convert between (compatible) units...
//!
//! ```
//! use newnit::Unit;
//! use newnit::area::imperial::SquareFoot;
//! use newnit::area::metric::SquareMeter;
//!
//! let bathroom_area = SquareMeter(6.0);
//! let bathroom_area_in_sq_feet = SquareFoot::from(&bathroom_area);
//! ```
//!
//! ... and get compile time protection against inadvertent use:
//!
//! ```compile_fail
//! use newnit::Unit;
//! use newnit::area::metric::SquareMeter;
//! use newnit::mass::metric::KiloGram;
//!
//! let bathroom_area = SquareMeter(6.0);
//!
//! // This is a compile error!
//! let bad_conversion = KiloGram::from(&bathroom_area);
//! ```
//!
//! Use the units in common mathematical operations:
//!
//! ```
//! use newnit::length::imperial::Foot;
//! use newnit::length::metric::Meter;
//!
//! let meters = Meter(4.0);
//! let feet = Foot(2.0);
//!
//! let sum = meters + &feet;
//! ```
//!
//! ```
//! use newnit::length::imperial::Foot;
//! use newnit::length::metric::Meter;
//!
//! let meters = Meter(4.0);
//!
//! let times_three = 3.0 * meters;
//!
//! let divided_by_negative_five = meters / -5.0;
//! ```
//!
//! ```
//! use newnit::length::Length;
//! use newnit::length::metric::Meter;
//! use newnit::time::metric::Second;
//! use newnit::velocity::metric::MeterPerSecond;
//!
//! let meters = Meter(4.0);
//! let seconds = Second(3.1);
//!
//! let speed: MeterPerSecond = meters.divide_time(&seconds);
//! ```
//!
//! Define your own unit with a derive macro:
//!
//! ```
//! use newnit::Unit;
//! use newnit::derive::{Mass, Unit};
//! use newnit::mass::Mass;
//!
//! #[derive(Unit, Mass)]
//! #[unit(factor = 6000.0)]
//! #[quantity(ops)] // opt in to provided mathematical Ops implementations
//! struct Elephants(f64);
//! ```
//!
//! [newtype]: https://rust-unofficial.github.io/patterns/patterns/behavioural/newtype.html
pub use newnit_derive as derive;
pub use Unit;