Skip to main content

blockworx/document/
linear_distance.rs

1use serde::{Deserialize, Serialize};
2
3const UNIT_SCALE: f64 = 16_777_216.0;
4
5#[derive(Clone, Copy, PartialEq, Debug, PartialOrd, Ord, Eq, Serialize, Deserialize)]
6pub struct LinearDistance(i64);
7
8impl LinearDistance {
9    /// The fixed-point representation. Persisting this rather than the `f32`
10    /// view is what makes a stored distance round-trip exactly.
11    pub const fn raw(self) -> i64 {
12        self.0
13    }
14
15    pub const fn from_raw(raw: i64) -> Self {
16        Self(raw)
17    }
18}
19
20impl From<f32> for LinearDistance {
21    fn from(value: f32) -> Self {
22        LinearDistance((value * UNIT_SCALE as f32) as i64)
23    }
24}
25
26impl From<f64> for LinearDistance {
27    fn from(value: f64) -> Self {
28        LinearDistance((value * UNIT_SCALE) as i64)
29    }
30}
31
32impl From<LinearDistance> for f32 {
33    fn from(value: LinearDistance) -> Self {
34        value.0 as f32 / UNIT_SCALE as f32
35    }
36}
37
38impl std::ops::Add<LinearDistance> for LinearDistance {
39    type Output = LinearDistance;
40
41    fn add(self, rhs: LinearDistance) -> Self::Output {
42        LinearDistance(self.0 + rhs.0)
43    }
44}
45
46impl std::ops::AddAssign<f32> for LinearDistance {
47    fn add_assign(&mut self, rhs: f32) {
48        *self = LinearDistance::from(f32::from(*self) + rhs);
49    }
50}
51
52impl std::ops::Mul<f32> for LinearDistance {
53    type Output = LinearDistance;
54
55    fn mul(self, rhs: f32) -> Self::Output {
56        LinearDistance::from(f32::from(self) * rhs)
57    }
58}
59
60impl std::ops::Mul<f64> for LinearDistance {
61    type Output = LinearDistance;
62
63    fn mul(self, rhs: f64) -> Self::Output {
64        LinearDistance::from(f32::from(self) * rhs as f32)
65    }
66}
67
68impl std::ops::Sub<LinearDistance> for LinearDistance {
69    type Output = LinearDistance;
70
71    fn sub(self, rhs: LinearDistance) -> Self::Output {
72        LinearDistance(self.0 - rhs.0)
73    }
74}