iridium_units/unit/base.rs
1//! Base unit definitions.
2//!
3//! Base units are the fundamental building blocks of the unit system.
4//! They are `Copy` types defined as `const` values in [`crate::systems`].
5//!
6//! # Examples
7//!
8//! ```
9//! use iridium_units::prelude::*;
10//!
11//! // Predefined base units are const and Copy
12//! let distance = 42.195 * KM;
13//! let in_miles = distance.to(MILE).unwrap();
14//!
15//! // Create composite units with arithmetic
16//! let accel = 9.8 * &(M / S.pow(2));
17//!
18//! // Access unit metadata
19//! assert_eq!(M.symbol, "m");
20//! assert_eq!(M.name, "meter");
21//! assert_eq!(M.dimension(), Dimension::LENGTH);
22//! ```
23
24use crate::dimension::Dimension;
25use std::fmt;
26
27/// An irreducible base unit like meter, second, or kilogram.
28#[derive(Clone, Copy, PartialEq)]
29pub struct BaseUnit {
30 /// Primary name (e.g., "meter")
31 pub name: &'static str,
32 /// Short symbol (e.g., "m")
33 pub symbol: &'static str,
34 /// Alternative names/aliases
35 pub aliases: &'static [&'static str],
36 /// The dimension this unit represents
37 pub dimension: Dimension,
38 /// Scale relative to the canonical SI base unit (1.0 for SI base units)
39 pub scale: f64,
40 /// Additive offset for converting to SI: `SI = (value + offset) * scale`.
41 /// Zero for most units. Celsius has offset 273.15 (K = °C + 273.15).
42 pub offset: f64,
43}
44
45impl BaseUnit {
46 /// Create a new base unit.
47 pub const fn new(
48 name: &'static str,
49 symbol: &'static str,
50 aliases: &'static [&'static str],
51 dimension: Dimension,
52 scale: f64,
53 ) -> Self {
54 BaseUnit {
55 name,
56 symbol,
57 aliases,
58 dimension,
59 scale,
60 offset: 0.0,
61 }
62 }
63
64 /// Create a new base unit with an additive offset.
65 /// Offset units use affine conversion via their `scale` and `offset`.
66 pub const fn with_offset(
67 name: &'static str,
68 symbol: &'static str,
69 aliases: &'static [&'static str],
70 dimension: Dimension,
71 scale: f64,
72 offset: f64,
73 ) -> Self {
74 BaseUnit {
75 name,
76 symbol,
77 aliases,
78 dimension,
79 scale,
80 offset,
81 }
82 }
83}
84
85impl BaseUnit {
86 /// Get the dimension of this unit.
87 pub const fn dimension(&self) -> Dimension {
88 self.dimension
89 }
90
91 /// Raise this unit to a power, returning a [`Unit`](crate::Unit).
92 pub fn pow(&self, exp: impl Into<crate::dimension::Rational16>) -> crate::Unit {
93 crate::Unit::from(*self).pow(exp)
94 }
95}
96
97impl fmt::Debug for BaseUnit {
98 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
99 write!(f, "BaseUnit({})", self.symbol)
100 }
101}
102
103impl fmt::Display for BaseUnit {
104 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
105 write!(f, "{}", self.symbol)
106 }
107}