tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

distance.rs (4234B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
      4 
      5 //! Machinery to compute distances between animatable values.
      6 
      7 use crate::derives::*;
      8 use app_units::Au;
      9 use euclid::default::Size2D;
     10 use std::iter::Sum;
     11 use std::ops::Add;
     12 
     13 /// A trait to compute squared distances between two animatable values.
     14 ///
     15 /// This trait is derivable with `#[derive(ComputeSquaredDistance)]`. The derived
     16 /// implementation uses a `match` expression with identical patterns for both
     17 /// `self` and `other`, calling `ComputeSquaredDistance::compute_squared_distance`
     18 /// on each fields of the values.
     19 ///
     20 /// If a variant is annotated with `#[animation(error)]`, the corresponding
     21 /// `match` arm returns an error.
     22 ///
     23 /// Trait bounds for type parameter `Foo` can be opted out of with
     24 /// `#[animation(no_bound(Foo))]` on the type definition, trait bounds for
     25 /// fields can be opted into with `#[distance(field_bound)]` on the field.
     26 pub trait ComputeSquaredDistance {
     27    /// Computes the squared distance between two animatable values.
     28    fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()>;
     29 }
     30 
     31 /// A distance between two animatable values.
     32 #[derive(Add, Clone, Copy, Debug, From, PartialEq, PartialOrd)]
     33 pub struct SquaredDistance {
     34    value: f64,
     35 }
     36 
     37 impl SquaredDistance {
     38    /// Returns a squared distance from its square root.
     39    #[inline]
     40    pub fn from_sqrt(sqrt: f64) -> Self {
     41        Self { value: sqrt * sqrt }
     42    }
     43 }
     44 
     45 impl ComputeSquaredDistance for u16 {
     46    #[inline]
     47    fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
     48        Ok(SquaredDistance::from_sqrt(
     49            ((*self as f64) - (*other as f64)).abs(),
     50        ))
     51    }
     52 }
     53 
     54 impl ComputeSquaredDistance for i16 {
     55    #[inline]
     56    fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
     57        Ok(SquaredDistance::from_sqrt((*self - *other).abs() as f64))
     58    }
     59 }
     60 
     61 impl ComputeSquaredDistance for i32 {
     62    #[inline]
     63    fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
     64        Ok(SquaredDistance::from_sqrt((*self - *other).abs() as f64))
     65    }
     66 }
     67 
     68 impl ComputeSquaredDistance for f32 {
     69    #[inline]
     70    fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
     71        Ok(SquaredDistance::from_sqrt((*self - *other).abs() as f64))
     72    }
     73 }
     74 
     75 impl ComputeSquaredDistance for f64 {
     76    #[inline]
     77    fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
     78        Ok(SquaredDistance::from_sqrt((*self - *other).abs()))
     79    }
     80 }
     81 
     82 impl ComputeSquaredDistance for Au {
     83    #[inline]
     84    fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
     85        self.0.compute_squared_distance(&other.0)
     86    }
     87 }
     88 
     89 impl<T> ComputeSquaredDistance for Box<T>
     90 where
     91    T: ComputeSquaredDistance,
     92 {
     93    #[inline]
     94    fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
     95        (**self).compute_squared_distance(&**other)
     96    }
     97 }
     98 
     99 impl<T> ComputeSquaredDistance for Option<T>
    100 where
    101    T: ComputeSquaredDistance,
    102 {
    103    #[inline]
    104    fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
    105        match (self.as_ref(), other.as_ref()) {
    106            (Some(this), Some(other)) => this.compute_squared_distance(other),
    107            (None, None) => Ok(SquaredDistance::from_sqrt(0.)),
    108            _ => Err(()),
    109        }
    110    }
    111 }
    112 
    113 impl<T> ComputeSquaredDistance for Size2D<T>
    114 where
    115    T: ComputeSquaredDistance,
    116 {
    117    #[inline]
    118    fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
    119        Ok(self.width.compute_squared_distance(&other.width)?
    120            + self.height.compute_squared_distance(&other.height)?)
    121    }
    122 }
    123 
    124 impl SquaredDistance {
    125    /// Returns the square root of this squared distance.
    126    #[inline]
    127    pub fn sqrt(self) -> f64 {
    128        self.value.sqrt()
    129    }
    130 }
    131 
    132 impl Sum for SquaredDistance {
    133    fn sum<I>(iter: I) -> Self
    134    where
    135        I: Iterator<Item = Self>,
    136    {
    137        iter.fold(SquaredDistance::from_sqrt(0.), Add::add)
    138    }
    139 }