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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
//! Strongly typed physical quantities and conversions.
//!
//! `qtty` is the user-facing crate in this workspace. It re-exports the full API from `qtty-core` plus a curated set
//! of predefined units (time, angles, lengths, …).
//!
//! The core idea is: a value is always a `Quantity<U, S>`, where `U` is a zero-sized type describing the unit and
//! `S` is the scalar type (defaults to `f64`). This keeps units at compile time with no runtime overhead beyond
//! the scalar's size.
//!
//! # What this crate solves
//!
//! - Prevents mixing incompatible dimensions (you can't add metres to seconds).
//! - Makes unit conversion explicit and type-checked (`to::<TargetUnit>()`).
//! - Provides a small set of astronomy-friendly units (AU, light-year, solar mass/luminosity, …).
//! - Supports multiple scalar types (`f64`, `f32`, and optionally `Decimal`, `Rational64`, etc.).
//!
//! # What this crate does not try to solve
//!
//! - Arbitrary symbolic unit algebra (e.g. `m^2 * s^-1`) or automatic simplification of arbitrary expressions.
//! - A full SI-prefix system; only the units defined in this crate are available out of the box.
//!
//! # Quick start
//!
//! Convert degrees to radians:
//!
//! ```rust
//! use qtty::{Degrees, Radian};
//!
//! let a = Degrees::new(180.0);
//! let r = a.to::<Radian>();
//! assert!((r.value() - core::f64::consts::PI).abs() < 1e-12);
//! ```
//!
//! Compose and use derived units (velocity = length / time):
//!
//! ```rust
//! use qtty::{Kilometer, Kilometers, Second, Seconds};
//! use qtty::velocity::Velocity;
//!
//! let d = Kilometers::new(1_000.0);
//! let t = Seconds::new(100.0);
//! let v: Velocity<Kilometer, Second> = d / t;
//! assert!((v.value() - 10.0).abs() < 1e-12);
//! ```
//!
//! Using `f32` for memory efficiency:
//!
//! ```rust
//! use qtty::f32::{Degrees, Meters};
//!
//! let angle: Degrees = Degrees::new(45.0_f32);
//! let distance: Meters = Meters::new(100.0_f32);
//! ```
//!
//! # Incorrect usage (type error)
//!
//! ```compile_fail
//! use qtty::{Kilometers, Seconds};
//!
//! let d = Kilometers::new(1.0);
//! let t = Seconds::new(1.0);
//! let _ = d + t; // cannot add different unit types
//! ```
//!
//! # Scalar Types
//!
//! The default scalar type is `f64`. You can use different scalar types:
//!
//! - `f64` (default) - double precision floating point
//! - `f32` - single precision floating point (use `qtty::f32::*`)
//! - `i8`, `i16`, `i32`, `i64`, `i128` - signed integers
//! (use `qtty::i8::*`, `qtty::i16::*`, `qtty::i32::*`, `qtty::i64::*`, `qtty::i128::*`)
//! - `Decimal` - exact decimal (feature `scalar-decimal`)
//! - `Rational64` - exact rational (feature `scalar-rational`)
//!
//! Integer quantities provide compile-time unit safety for discrete values.
//! They support basic arithmetic and lossy unit conversion via
//! [`to_lossy()`](crate::Quantity::to_lossy), but not the full [`to()`](crate::Quantity::to)
//! method (which requires floating-point semantics).
//!
//! # Modules
//!
//! Units are grouped by dimension under modules (also re-exported at the crate root for convenience):
//!
//! - `qtty::angular` (degrees, radians, arcseconds, wrapping/trigonometry helpers)
//! - `qtty::time` (seconds, days, years, …)
//! - `qtty::length` (metres, kilometres, AU, light-year, …)
//! - `qtty::mass` (grams, kilograms, solar mass)
//! - `qtty::power` (watts, solar luminosity)
//! - `qtty::velocity` (`Length / Time` aliases)
//! - `qtty::frequency` (`Angular / Time` aliases)
//! - `qtty::f32` (all units with `f32` scalar)
//! - `qtty::f64` (all units with `f64` scalar - same as root)
//! - `qtty::i8` (all units with `i8` scalar)
//! - `qtty::i16` (all units with `i16` scalar)
//! - `qtty::i32` (all units with `i32` scalar)
//! - `qtty::i64` (all units with `i64` scalar)
//! - `qtty::i128` (all units with `i128` scalar)
//!
//! # Feature flags
//!
//! - `std` (default): enables `std` support in `qtty-core`.
//! - `cross-unit-ops` (default): enables direct cross-unit comparison operators (`==`, `<`, etc.) for built-in units.
//! - `alloc`: enables heap-backed helpers (like `qtty_vec!(vec ...)`) in `no_std` builds.
//! - `serde`: enables `serde` support for `Quantity<U>`; serialization is the raw `f64` value only.
//! - `scalar-decimal`: enables `rust_decimal::Decimal` as a scalar type.
//! - `scalar-rational`: enables `num_rational::Rational64` as a scalar type.
//!
//! Disable default features for `no_std`:
//!
//! ```toml
//! [dependencies]
//! qtty = { version = "0.2.0", default-features = false }
//! ```
//!
//! If you need `qtty_vec!(vec ...)` in `no_std`, enable `alloc`:
//!
//! ```toml
//! [dependencies]
//! qtty = { version = "0.2.0", default-features = false, features = ["alloc"] }
//! ```
//!
//! # Panics and errors
//!
//! This crate does not define an error type and does not return `Result` from its core operations. Conversions and
//! arithmetic are pure computations; they do not panic on their own, but they follow IEEE-754 behavior for floats
//! (NaN and infinities propagate according to the underlying operation).
//!
//! # SemVer and stability
//!
//! This workspace is currently `0.x`. Expect breaking changes between minor versions until `1.0`.
extern crate alloc;
pub use *;
/// Derive macro used by `qtty-core` to define unit marker types.
///
/// This macro expands in terms of `crate::Unit` and `crate::Quantity`, so it is intended for use inside `qtty-core`
/// (or crates exposing the same crate-root API). Most users should not need this.
pub use Unit;
// ─────────────────────────────────────────────────────────────────────────────
// Scalar-specific modules
// ─────────────────────────────────────────────────────────────────────────────
// ─────────────────────────────────────────────────────────────────────────────
// Unit modules (grouped by dimension)
// ─────────────────────────────────────────────────────────────────────────────
pub use angular;
pub use area;
pub use frequency;
pub use length;
pub use mass;
pub use power;
pub use time;
pub use unitless;
pub use velocity;
pub use volume;
// ─────────────────────────────────────────────────────────────────────────────
// Convenience re-exports (default f64 types)
// ─────────────────────────────────────────────────────────────────────────────
pub use *;
pub use *;
pub use *;
pub use *;
pub use *;
pub use *;
pub use *;
pub use *;
pub use *;
/// Build typed quantities from scalar literals without repeating `Unit::new(...)`.
///
/// # Forms
///
/// - Array (const-friendly):
/// `qtty::qtty_vec!(Seconds; 1.0, 2.0, 3.0)`
/// - Vector:
/// `qtty::qtty_vec!(vec Seconds; 1.0, 2.0, 3.0)` (requires `std` or `alloc`)
///
/// # Examples
///
/// ```
/// use qtty::Seconds;
///
/// const OFFSETS: [Seconds; 3] = qtty::qtty_vec!(Seconds; 56.86, 63.83, 70.0);
/// assert_eq!(OFFSETS[1].value(), 63.83);
///
/// let samples: Vec<Seconds> = qtty::qtty_vec!(vec Seconds; 1.0, 2.0, 3.0);
/// assert_eq!(samples.len(), 3);
/// ```