1use anyhow::anyhow;
2
3pub mod dimensionless;
4pub mod energy;
5pub mod length;
6pub(crate) mod macros;
7pub mod mass;
8pub mod temperature;
9pub mod time;
10pub mod traits;
11
12pub use dimensionless::DimensionlessFloat;
13pub use traits::FloatingPointUnit;
14
15pub type DimensionlessPositiveFloat = PositiveFloat;
17
18pub type KmPerSecPerMpc = f64;
20pub type HInvKmPerSecPerMpc = f64;
21
22pub type KilogramsPerMeter3 = PositiveFloat;
24
25pub type MetersPerSecond = f64;
28pub type Meters3PerKgPerSecond2 = f64;
29pub type Meters2KgPerSecond2Kelvin = f64;
30pub type JouleSeconds = f64;
31pub type JoulePerMeter3Kelvin4 = f64;
32pub type WattsPerMeters2Kelvin4 = f64;
33pub type JoulePerKelvin = f64;
34pub type Mpc3 = f64;
35pub type HInvMpc = f64;
36
37#[derive(Clone, Copy, Debug, PartialOrd, PartialEq)]
39pub struct PositiveFloat(pub f64);
40
41impl PositiveFloat {
42 pub fn new(x: f64) -> Result<Self, anyhow::Error> {
43 if x < 0. {
44 return Err(anyhow!("expected positive number"));
45 }
46 Ok(Self(x))
47 }
48
49 pub fn zero() -> Self {
50 Self(0.)
51 }
52
53 pub fn one() -> Self {
54 Self(1.)
55 }
56
57 pub fn floor(&self) -> f64 {
59 self.0.floor()
60 }
61
62 pub fn powf(&self, exp: f64) -> f64 {
63 self.0.powf(exp)
64 }
65}
66
67impl std::ops::Sub for PositiveFloat {
68 type Output = PositiveFloat;
69
70 fn sub(self, rhs: Self) -> Self::Output {
71 PositiveFloat(self.0 - rhs.0)
72 }
73}
74
75impl std::ops::Add for PositiveFloat {
76 type Output = PositiveFloat;
77
78 fn add(self, rhs: Self) -> Self::Output {
79 PositiveFloat(self.0 + rhs.0)
80 }
81}