#### Source code

#### Revision control

#### Copy as Markdown

#### Other Tools

```
/* This Source Code Form is subject to the terms of the Mozilla Public
```

```
* License, v. 2.0. If a copy of the MPL was not distributed with this
```

```
```

```
//! Machinery to compute distances between animatable values.
```

```
```

```
use app_units::Au;
```

```
use euclid::default::Size2D;
```

```
use std::iter::Sum;
```

```
use std::ops::Add;
```

```
```

```
/// A trait to compute squared distances between two animatable values.
```

```
///
```

```
/// This trait is derivable with `#[derive(ComputeSquaredDistance)]`. The derived
```

```
/// implementation uses a `match` expression with identical patterns for both
```

```
/// `self` and `other`, calling `ComputeSquaredDistance::compute_squared_distance`
```

```
/// on each fields of the values.
```

```
///
```

```
/// If a variant is annotated with `#[animation(error)]`, the corresponding
```

```
/// `match` arm returns an error.
```

```
///
```

```
/// Trait bounds for type parameter `Foo` can be opted out of with
```

```
/// `#[animation(no_bound(Foo))]` on the type definition, trait bounds for
```

```
/// fields can be opted into with `#[distance(field_bound)]` on the field.
```

```
pub trait ComputeSquaredDistance {
```

```
/// Computes the squared distance between two animatable values.
```

```
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()>;
```

```
}
```

```
```

```
/// A distance between two animatable values.
```

```
#[derive(Add, Clone, Copy, Debug, From)]
```

```
pub struct SquaredDistance {
```

```
value: f64,
```

```
}
```

```
```

```
impl SquaredDistance {
```

```
/// Returns a squared distance from its square root.
```

```
#[inline]
```

```
pub fn from_sqrt(sqrt: f64) -> Self {
```

```
Self { value: sqrt * sqrt }
```

```
}
```

```
}
```

```
```

```
impl ComputeSquaredDistance for u16 {
```

```
#[inline]
```

```
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
```

```
Ok(SquaredDistance::from_sqrt(
```

```
((*self as f64) - (*other as f64)).abs(),
```

```
))
```

```
}
```

```
}
```

```
```

```
impl ComputeSquaredDistance for i16 {
```

```
#[inline]
```

```
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
```

```
Ok(SquaredDistance::from_sqrt((*self - *other).abs() as f64))
```

```
}
```

```
}
```

```
```

```
impl ComputeSquaredDistance for i32 {
```

```
#[inline]
```

```
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
```

```
Ok(SquaredDistance::from_sqrt((*self - *other).abs() as f64))
```

```
}
```

```
}
```

```
```

```
impl ComputeSquaredDistance for f32 {
```

```
#[inline]
```

```
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
```

```
Ok(SquaredDistance::from_sqrt((*self - *other).abs() as f64))
```

```
}
```

```
}
```

```
```

```
impl ComputeSquaredDistance for f64 {
```

```
#[inline]
```

```
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
```

```
Ok(SquaredDistance::from_sqrt((*self - *other).abs()))
```

```
}
```

```
}
```

```
```

```
impl ComputeSquaredDistance for Au {
```

```
#[inline]
```

```
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
```

```
self.0.compute_squared_distance(&other.0)
```

```
}
```

```
}
```

```
```

```
impl<T> ComputeSquaredDistance for Box<T>
```

```
where
```

```
T: ComputeSquaredDistance,
```

```
{
```

```
#[inline]
```

```
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
```

```
(**self).compute_squared_distance(&**other)
```

```
}
```

```
}
```

```
```

```
impl<T> ComputeSquaredDistance for Option<T>
```

```
where
```

```
T: ComputeSquaredDistance,
```

```
{
```

```
#[inline]
```

```
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
```

```
match (self.as_ref(), other.as_ref()) {
```

```
(Some(this), Some(other)) => this.compute_squared_distance(other),
```

```
(None, None) => Ok(SquaredDistance::from_sqrt(0.)),
```

```
_ => Err(()),
```

```
}
```

```
}
```

```
}
```

```
```

```
impl<T> ComputeSquaredDistance for Size2D<T>
```

```
where
```

```
T: ComputeSquaredDistance,
```

```
{
```

```
#[inline]
```

```
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
```

```
Ok(self.width.compute_squared_distance(&other.width)? +
```

```
self.height.compute_squared_distance(&other.height)?)
```

```
}
```

```
}
```

```
```

```
impl SquaredDistance {
```

```
/// Returns the square root of this squared distance.
```

```
#[inline]
```

```
pub fn sqrt(self) -> f64 {
```

```
self.value.sqrt()
```

```
}
```

```
}
```

```
```

```
impl Sum for SquaredDistance {
```

```
fn sum<I>(iter: I) -> Self
```

```
where
```

```
I: Iterator<Item = Self>,
```

```
{
```

```
iter.fold(SquaredDistance::from_sqrt(0.), Add::add)
```

```
}
```

```
}
```