elevator_core/components/
units.rs1use serde::{Deserialize, Serialize};
4use std::fmt;
5
6#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Serialize, Deserialize)]
17#[serde(transparent)]
18pub struct Weight {
19 pub(crate) value: f64,
21}
22
23impl Weight {
24 pub const ZERO: Self = Self { value: 0.0 };
26
27 #[must_use]
29 pub const fn value(self) -> f64 {
30 self.value
31 }
32}
33
34impl fmt::Display for Weight {
35 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
36 write!(f, "{:.2}kg", self.value)
37 }
38}
39
40impl From<f64> for Weight {
41 fn from(value: f64) -> Self {
42 debug_assert!(
43 value.is_finite() && value >= 0.0,
44 "Weight must be finite and non-negative, got {value}"
45 );
46 Self { value }
47 }
48}
49
50impl std::ops::Add for Weight {
51 type Output = Self;
52 fn add(self, rhs: Self) -> Self {
53 Self {
54 value: self.value + rhs.value,
55 }
56 }
57}
58
59impl std::ops::AddAssign for Weight {
60 fn add_assign(&mut self, rhs: Self) {
61 self.value += rhs.value;
62 }
63}
64
65impl std::ops::Sub for Weight {
66 type Output = Self;
67 fn sub(self, rhs: Self) -> Self {
68 Self {
69 value: (self.value - rhs.value).max(0.0),
70 }
71 }
72}
73
74impl std::ops::SubAssign for Weight {
75 fn sub_assign(&mut self, rhs: Self) {
76 self.value = (self.value - rhs.value).max(0.0);
77 }
78}
79
80#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Serialize, Deserialize)]
88#[serde(transparent)]
89pub struct Speed {
90 pub(crate) value: f64,
92}
93
94impl Speed {
95 #[must_use]
97 pub const fn value(self) -> f64 {
98 self.value
99 }
100}
101
102impl fmt::Display for Speed {
103 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
104 write!(f, "{:.2}m/s", self.value)
105 }
106}
107
108impl From<f64> for Speed {
109 fn from(value: f64) -> Self {
110 debug_assert!(
111 value.is_finite() && value >= 0.0,
112 "Speed must be finite and non-negative, got {value}"
113 );
114 Self { value }
115 }
116}
117
118#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Serialize, Deserialize)]
126#[serde(transparent)]
127pub struct Accel {
128 pub(crate) value: f64,
130}
131
132impl Accel {
133 #[must_use]
135 pub const fn value(self) -> f64 {
136 self.value
137 }
138}
139
140impl fmt::Display for Accel {
141 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
142 write!(f, "{:.2}m/s²", self.value)
143 }
144}
145
146impl From<f64> for Accel {
147 fn from(value: f64) -> Self {
148 debug_assert!(
149 value.is_finite() && value >= 0.0,
150 "Accel must be finite and non-negative, got {value}"
151 );
152 Self { value }
153 }
154}