1use app_units::Au;
8use euclid::default::Size2D;
9use std::iter::Sum;
10use std::ops::Add;
11
12pub trait ComputeSquaredDistance {
26 fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()>;
28}
29
30#[derive(Add, Clone, Copy, Debug, From, PartialEq, PartialOrd)]
32pub struct SquaredDistance {
33 value: f64,
34}
35
36impl SquaredDistance {
37 #[inline]
39 pub fn from_sqrt(sqrt: f64) -> Self {
40 Self { value: sqrt * sqrt }
41 }
42}
43
44impl ComputeSquaredDistance for u16 {
45 #[inline]
46 fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
47 Ok(SquaredDistance::from_sqrt(
48 ((*self as f64) - (*other as f64)).abs(),
49 ))
50 }
51}
52
53impl ComputeSquaredDistance for i16 {
54 #[inline]
55 fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
56 Ok(SquaredDistance::from_sqrt((*self - *other).abs() as f64))
57 }
58}
59
60impl ComputeSquaredDistance for i32 {
61 #[inline]
62 fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
63 Ok(SquaredDistance::from_sqrt((*self - *other).abs() as f64))
64 }
65}
66
67impl ComputeSquaredDistance for f32 {
68 #[inline]
69 fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
70 Ok(SquaredDistance::from_sqrt((*self - *other).abs() as f64))
71 }
72}
73
74impl ComputeSquaredDistance for f64 {
75 #[inline]
76 fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
77 Ok(SquaredDistance::from_sqrt((*self - *other).abs()))
78 }
79}
80
81impl ComputeSquaredDistance for Au {
82 #[inline]
83 fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
84 self.0.compute_squared_distance(&other.0)
85 }
86}
87
88impl<T> ComputeSquaredDistance for Box<T>
89where
90 T: ComputeSquaredDistance,
91{
92 #[inline]
93 fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
94 (**self).compute_squared_distance(&**other)
95 }
96}
97
98impl<T> ComputeSquaredDistance for Option<T>
99where
100 T: ComputeSquaredDistance,
101{
102 #[inline]
103 fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
104 match (self.as_ref(), other.as_ref()) {
105 (Some(this), Some(other)) => this.compute_squared_distance(other),
106 (None, None) => Ok(SquaredDistance::from_sqrt(0.)),
107 _ => Err(()),
108 }
109 }
110}
111
112impl<T> ComputeSquaredDistance for Size2D<T>
113where
114 T: ComputeSquaredDistance,
115{
116 #[inline]
117 fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
118 Ok(self.width.compute_squared_distance(&other.width)?
119 + self.height.compute_squared_distance(&other.height)?)
120 }
121}
122
123impl SquaredDistance {
124 #[inline]
126 pub fn sqrt(self) -> f64 {
127 self.value.sqrt()
128 }
129}
130
131impl Sum for SquaredDistance {
132 fn sum<I>(iter: I) -> Self
133 where
134 I: Iterator<Item = Self>,
135 {
136 iter.fold(SquaredDistance::from_sqrt(0.), Add::add)
137 }
138}