space_units/lib.rs
1//! # space-units
2//!
3//! Type-safe units of measure for aerospace quantities.
4//!
5//! This crate provides **40 concrete newtypes** for physical quantities
6//! ([`Length`], [`Mass`], [`Velocity`], [`Force`], [`Voltage`], [`Temperature`], ...)
7//! where only physically meaningful arithmetic compiles, conversions are explicit,
8//! and units are always part of the type.
9//!
10//! ## Quick Start
11//!
12//! ```
13//! use space_units::prelude::*;
14//!
15//! let distance = 384_400.km(); // Length
16//! let time = 3.days(); // Time
17//! let velocity = distance / time; // Length / Time → Velocity
18//!
19//! let force = 1000.kg() * 9.81.mps2(); // Mass * Acceleration → Force
20//! ```
21//!
22//! ## Key Features
23//!
24//! - **82 typed arithmetic operations** — `Length / Time → Velocity`, `Voltage * Current → Power`, etc.
25//! - **[`NumericExt`] literal extensions** — `384_400.km()`, `51.6.deg()`, `28.volts()`
26//! - **34 typed constants** — [`constants::GM_EARTH`], [`constants::C`], [`constants::AU`], etc.
27//! - **Zero dependencies**, `no_std` compatible, `const fn` constructors
28//!
29//! Import [`prelude`] for the common case:
30//!
31//! ```
32//! use space_units::prelude::*;
33//! ```
34
35#![cfg_attr(not(feature = "std"), no_std)]
36#![forbid(unsafe_code)]
37
38pub mod constants;
39pub mod prelude;
40
41mod numeric_ext;
42mod quantities;
43
44pub use crate::numeric_ext::NumericExt;
45pub use crate::quantities::*;
46
47/// Returns the smaller of two values using `PartialOrd`.
48///
49/// This exists because `std::cmp::min` requires `Ord`, but quantities are
50/// float-backed and only `PartialOrd`.
51pub fn min<T: Copy + PartialOrd>(a: T, b: T) -> T {
52 if a <= b {
53 a
54 } else {
55 b
56 }
57}
58
59/// Returns the larger of two values using `PartialOrd`.
60///
61/// This exists because `std::cmp::max` requires `Ord`, but quantities are
62/// float-backed and only `PartialOrd`.
63pub fn max<T: Copy + PartialOrd>(a: T, b: T) -> T {
64 if a >= b {
65 a
66 } else {
67 b
68 }
69}