euclid/
length.rs

1// Copyright 2014 The Servo Project Developers. See the COPYRIGHT
2// file at the top-level directory of this distribution.
3//
4// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
5// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
7// option. This file may not be copied, modified, or distributed
8// except according to those terms.
9//! A one-dimensional length, tagged with its units.
10
11use crate::approxeq::ApproxEq;
12use crate::approxord::{max, min};
13use crate::num::Zero;
14use crate::scale::Scale;
15
16use crate::num::One;
17#[cfg(feature = "bytemuck")]
18use bytemuck::{Pod, Zeroable};
19use core::cmp::Ordering;
20use core::fmt;
21use core::hash::{Hash, Hasher};
22use core::iter::Sum;
23use core::marker::PhantomData;
24use core::ops::{Add, Div, Mul, Neg, Sub};
25use core::ops::{AddAssign, DivAssign, MulAssign, SubAssign};
26use num_traits::{NumCast, Saturating};
27#[cfg(feature = "serde")]
28use serde::{Deserialize, Deserializer, Serialize, Serializer};
29
30/// A one-dimensional distance, with value represented by `T` and unit of measurement `Unit`.
31///
32/// `T` can be any numeric type, for example a primitive type like `u64` or `f32`.
33///
34/// `Unit` is not used in the representation of a `Length` value. It is used only at compile time
35/// to ensure that a `Length` stored with one unit is converted explicitly before being used in an
36/// expression that requires a different unit.  It may be a type without values, such as an empty
37/// enum.
38///
39/// You can multiply a `Length` by a [`Scale`] to convert it from one unit to
40/// another. See the [`Scale`] docs for an example.
41#[repr(C)]
42pub struct Length<T, Unit>(pub T, #[doc(hidden)] pub PhantomData<Unit>);
43
44impl<T: Clone, U> Clone for Length<T, U> {
45    fn clone(&self) -> Self {
46        Length(self.0.clone(), PhantomData)
47    }
48}
49
50impl<T: Copy, U> Copy for Length<T, U> {}
51
52#[cfg(feature = "serde")]
53impl<'de, T, U> Deserialize<'de> for Length<T, U>
54where
55    T: Deserialize<'de>,
56{
57    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
58    where
59        D: Deserializer<'de>,
60    {
61        Ok(Length(Deserialize::deserialize(deserializer)?, PhantomData))
62    }
63}
64
65#[cfg(feature = "serde")]
66impl<T, U> Serialize for Length<T, U>
67where
68    T: Serialize,
69{
70    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
71    where
72        S: Serializer,
73    {
74        self.0.serialize(serializer)
75    }
76}
77
78#[cfg(feature = "arbitrary")]
79impl<'a, T, U> arbitrary::Arbitrary<'a> for Length<T, U>
80where
81    T: arbitrary::Arbitrary<'a>,
82{
83    fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
84        Ok(Length(arbitrary::Arbitrary::arbitrary(u)?, PhantomData))
85    }
86}
87
88#[cfg(feature = "bytemuck")]
89unsafe impl<T: Zeroable, U> Zeroable for Length<T, U> {}
90
91#[cfg(feature = "bytemuck")]
92unsafe impl<T: Pod, U: 'static> Pod for Length<T, U> {}
93
94impl<T, U> Length<T, U> {
95    /// Associate a value with a unit of measure.
96    #[inline]
97    pub const fn new(x: T) -> Self {
98        Length(x, PhantomData)
99    }
100}
101
102impl<T: Clone, U> Length<T, U> {
103    /// Unpack the underlying value from the wrapper.
104    pub fn get(self) -> T {
105        self.0
106    }
107
108    /// Cast the unit
109    #[inline]
110    pub fn cast_unit<V>(self) -> Length<T, V> {
111        Length::new(self.0)
112    }
113
114    /// Linearly interpolate between this length and another length.
115    ///
116    /// # Example
117    ///
118    /// ```rust
119    /// use euclid::default::Length;
120    ///
121    /// let from = Length::new(0.0);
122    /// let to = Length::new(8.0);
123    ///
124    /// assert_eq!(from.lerp(to, -1.0), Length::new(-8.0));
125    /// assert_eq!(from.lerp(to,  0.0), Length::new( 0.0));
126    /// assert_eq!(from.lerp(to,  0.5), Length::new( 4.0));
127    /// assert_eq!(from.lerp(to,  1.0), Length::new( 8.0));
128    /// assert_eq!(from.lerp(to,  2.0), Length::new(16.0));
129    /// ```
130    #[inline]
131    pub fn lerp(self, other: Self, t: T) -> Self
132    where
133        T: One + Sub<Output = T> + Mul<Output = T> + Add<Output = T>,
134    {
135        let one_t = T::one() - t.clone();
136        Length::new(one_t * self.0.clone() + t * other.0)
137    }
138}
139
140impl<T: PartialOrd, U> Length<T, U> {
141    /// Returns minimum between this length and another length.
142    #[inline]
143    pub fn min(self, other: Self) -> Self {
144        min(self, other)
145    }
146
147    /// Returns maximum between this length and another length.
148    #[inline]
149    pub fn max(self, other: Self) -> Self {
150        max(self, other)
151    }
152}
153
154impl<T: NumCast + Clone, U> Length<T, U> {
155    /// Cast from one numeric representation to another, preserving the units.
156    #[inline]
157    pub fn cast<NewT: NumCast>(self) -> Length<NewT, U> {
158        self.try_cast().unwrap()
159    }
160
161    /// Fallible cast from one numeric representation to another, preserving the units.
162    pub fn try_cast<NewT: NumCast>(self) -> Option<Length<NewT, U>> {
163        NumCast::from(self.0).map(Length::new)
164    }
165}
166
167impl<T: fmt::Debug, U> fmt::Debug for Length<T, U> {
168    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
169        self.0.fmt(f)
170    }
171}
172
173impl<T: Default, U> Default for Length<T, U> {
174    #[inline]
175    fn default() -> Self {
176        Length::new(Default::default())
177    }
178}
179
180impl<T: Hash, U> Hash for Length<T, U> {
181    fn hash<H: Hasher>(&self, h: &mut H) {
182        self.0.hash(h);
183    }
184}
185
186// length + length
187impl<T: Add, U> Add for Length<T, U> {
188    type Output = Length<T::Output, U>;
189
190    fn add(self, other: Self) -> Self::Output {
191        Length::new(self.0 + other.0)
192    }
193}
194
195// length + &length
196impl<T: Add + Copy, U> Add<&Self> for Length<T, U> {
197    type Output = Length<T::Output, U>;
198
199    fn add(self, other: &Self) -> Self::Output {
200        Length::new(self.0 + other.0)
201    }
202}
203
204// length_iter.copied().sum()
205impl<T: Add<Output = T> + Zero, U> Sum for Length<T, U> {
206    fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
207        iter.fold(Self::zero(), Add::add)
208    }
209}
210
211// length_iter.sum()
212impl<'a, T: 'a + Add<Output = T> + Copy + Zero, U: 'a> Sum<&'a Self> for Length<T, U> {
213    fn sum<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
214        iter.fold(Self::zero(), Add::add)
215    }
216}
217
218// length += length
219impl<T: AddAssign, U> AddAssign for Length<T, U> {
220    fn add_assign(&mut self, other: Self) {
221        self.0 += other.0;
222    }
223}
224
225// length - length
226impl<T: Sub, U> Sub for Length<T, U> {
227    type Output = Length<T::Output, U>;
228
229    fn sub(self, other: Length<T, U>) -> Self::Output {
230        Length::new(self.0 - other.0)
231    }
232}
233
234// length -= length
235impl<T: SubAssign, U> SubAssign for Length<T, U> {
236    fn sub_assign(&mut self, other: Self) {
237        self.0 -= other.0;
238    }
239}
240
241// Saturating length + length and length - length.
242impl<T: Saturating, U> Saturating for Length<T, U> {
243    fn saturating_add(self, other: Self) -> Self {
244        Length::new(self.0.saturating_add(other.0))
245    }
246
247    fn saturating_sub(self, other: Self) -> Self {
248        Length::new(self.0.saturating_sub(other.0))
249    }
250}
251
252// length / length
253impl<Src, Dst, T: Div> Div<Length<T, Src>> for Length<T, Dst> {
254    type Output = Scale<T::Output, Src, Dst>;
255
256    #[inline]
257    fn div(self, other: Length<T, Src>) -> Self::Output {
258        Scale::new(self.0 / other.0)
259    }
260}
261
262// length * scalar
263impl<T: Mul, U> Mul<T> for Length<T, U> {
264    type Output = Length<T::Output, U>;
265
266    #[inline]
267    fn mul(self, scale: T) -> Self::Output {
268        Length::new(self.0 * scale)
269    }
270}
271
272// length *= scalar
273impl<T: Copy + Mul<T, Output = T>, U> MulAssign<T> for Length<T, U> {
274    #[inline]
275    fn mul_assign(&mut self, scale: T) {
276        *self = *self * scale
277    }
278}
279
280// length / scalar
281impl<T: Div, U> Div<T> for Length<T, U> {
282    type Output = Length<T::Output, U>;
283
284    #[inline]
285    fn div(self, scale: T) -> Self::Output {
286        Length::new(self.0 / scale)
287    }
288}
289
290// length /= scalar
291impl<T: Copy + Div<T, Output = T>, U> DivAssign<T> for Length<T, U> {
292    #[inline]
293    fn div_assign(&mut self, scale: T) {
294        *self = *self / scale
295    }
296}
297
298// length * scaleFactor
299impl<Src, Dst, T: Mul> Mul<Scale<T, Src, Dst>> for Length<T, Src> {
300    type Output = Length<T::Output, Dst>;
301
302    #[inline]
303    fn mul(self, scale: Scale<T, Src, Dst>) -> Self::Output {
304        Length::new(self.0 * scale.0)
305    }
306}
307
308// length / scaleFactor
309impl<Src, Dst, T: Div> Div<Scale<T, Src, Dst>> for Length<T, Dst> {
310    type Output = Length<T::Output, Src>;
311
312    #[inline]
313    fn div(self, scale: Scale<T, Src, Dst>) -> Self::Output {
314        Length::new(self.0 / scale.0)
315    }
316}
317
318// -length
319impl<U, T: Neg> Neg for Length<T, U> {
320    type Output = Length<T::Output, U>;
321
322    #[inline]
323    fn neg(self) -> Self::Output {
324        Length::new(-self.0)
325    }
326}
327
328impl<T: PartialEq, U> PartialEq for Length<T, U> {
329    fn eq(&self, other: &Self) -> bool {
330        self.0.eq(&other.0)
331    }
332}
333
334impl<T: PartialOrd, U> PartialOrd for Length<T, U> {
335    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
336        self.0.partial_cmp(&other.0)
337    }
338}
339
340impl<T: Eq, U> Eq for Length<T, U> {}
341
342impl<T: Ord, U> Ord for Length<T, U> {
343    fn cmp(&self, other: &Self) -> Ordering {
344        self.0.cmp(&other.0)
345    }
346}
347
348impl<T: Zero, U> Zero for Length<T, U> {
349    #[inline]
350    fn zero() -> Self {
351        Length::new(Zero::zero())
352    }
353}
354
355impl<U, T: ApproxEq<T>> ApproxEq<T> for Length<T, U> {
356    #[inline]
357    fn approx_epsilon() -> T {
358        T::approx_epsilon()
359    }
360
361    #[inline]
362    fn approx_eq_eps(&self, other: &Length<T, U>, approx_epsilon: &T) -> bool {
363        self.0.approx_eq_eps(&other.0, approx_epsilon)
364    }
365}
366
367#[cfg(test)]
368mod tests {
369    use super::Length;
370    use crate::num::Zero;
371
372    use crate::scale::Scale;
373    use core::f32::INFINITY;
374    use num_traits::Saturating;
375
376    enum Inch {}
377    enum Mm {}
378    enum Cm {}
379    enum Second {}
380
381    #[cfg(feature = "serde")]
382    mod serde {
383        use super::*;
384
385        extern crate serde_test;
386        use self::serde_test::assert_tokens;
387        use self::serde_test::Token;
388
389        #[test]
390        fn test_length_serde() {
391            let one_cm: Length<f32, Mm> = Length::new(10.0);
392
393            assert_tokens(&one_cm, &[Token::F32(10.0)]);
394        }
395    }
396
397    #[test]
398    fn test_clone() {
399        // A cloned Length is a separate length with the state matching the
400        // original Length at the point it was cloned.
401        let mut variable_length: Length<f32, Inch> = Length::new(12.0);
402
403        let one_foot = variable_length.clone();
404        variable_length.0 = 24.0;
405
406        assert_eq!(one_foot.get(), 12.0);
407        assert_eq!(variable_length.get(), 24.0);
408    }
409
410    #[test]
411    fn test_add() {
412        let length1: Length<u8, Mm> = Length::new(250);
413        let length2: Length<u8, Mm> = Length::new(5);
414
415        assert_eq!((length1 + length2).get(), 255);
416        assert_eq!((length1 + &length2).get(), 255);
417    }
418
419    #[test]
420    fn test_sum() {
421        type L = Length<f32, Mm>;
422        let lengths = [L::new(1.0), L::new(2.0), L::new(3.0)];
423
424        assert_eq!(lengths.iter().sum::<L>(), L::new(6.0));
425    }
426
427    #[test]
428    fn test_addassign() {
429        let one_cm: Length<f32, Mm> = Length::new(10.0);
430        let mut measurement: Length<f32, Mm> = Length::new(5.0);
431
432        measurement += one_cm;
433
434        assert_eq!(measurement.get(), 15.0);
435    }
436
437    #[test]
438    fn test_sub() {
439        let length1: Length<u8, Mm> = Length::new(250);
440        let length2: Length<u8, Mm> = Length::new(5);
441
442        let result = length1 - length2;
443
444        assert_eq!(result.get(), 245);
445    }
446
447    #[test]
448    fn test_subassign() {
449        let one_cm: Length<f32, Mm> = Length::new(10.0);
450        let mut measurement: Length<f32, Mm> = Length::new(5.0);
451
452        measurement -= one_cm;
453
454        assert_eq!(measurement.get(), -5.0);
455    }
456
457    #[test]
458    fn test_saturating_add() {
459        let length1: Length<u8, Mm> = Length::new(250);
460        let length2: Length<u8, Mm> = Length::new(6);
461
462        let result = length1.saturating_add(length2);
463
464        assert_eq!(result.get(), 255);
465    }
466
467    #[test]
468    fn test_saturating_sub() {
469        let length1: Length<u8, Mm> = Length::new(5);
470        let length2: Length<u8, Mm> = Length::new(10);
471
472        let result = length1.saturating_sub(length2);
473
474        assert_eq!(result.get(), 0);
475    }
476
477    #[test]
478    fn test_division_by_length() {
479        // Division results in a Scale from denominator units
480        // to numerator units.
481        let length: Length<f32, Cm> = Length::new(5.0);
482        let duration: Length<f32, Second> = Length::new(10.0);
483
484        let result = length / duration;
485
486        let expected: Scale<f32, Second, Cm> = Scale::new(0.5);
487        assert_eq!(result, expected);
488    }
489
490    #[test]
491    fn test_multiplication() {
492        let length_mm: Length<f32, Mm> = Length::new(10.0);
493        let cm_per_mm: Scale<f32, Mm, Cm> = Scale::new(0.1);
494
495        let result = length_mm * cm_per_mm;
496
497        let expected: Length<f32, Cm> = Length::new(1.0);
498        assert_eq!(result, expected);
499    }
500
501    #[test]
502    fn test_multiplication_with_scalar() {
503        let length_mm: Length<f32, Mm> = Length::new(10.0);
504
505        let result = length_mm * 2.0;
506
507        let expected: Length<f32, Mm> = Length::new(20.0);
508        assert_eq!(result, expected);
509    }
510
511    #[test]
512    fn test_multiplication_assignment() {
513        let mut length: Length<f32, Mm> = Length::new(10.0);
514
515        length *= 2.0;
516
517        let expected: Length<f32, Mm> = Length::new(20.0);
518        assert_eq!(length, expected);
519    }
520
521    #[test]
522    fn test_division_by_scalefactor() {
523        let length: Length<f32, Cm> = Length::new(5.0);
524        let cm_per_second: Scale<f32, Second, Cm> = Scale::new(10.0);
525
526        let result = length / cm_per_second;
527
528        let expected: Length<f32, Second> = Length::new(0.5);
529        assert_eq!(result, expected);
530    }
531
532    #[test]
533    fn test_division_by_scalar() {
534        let length: Length<f32, Cm> = Length::new(5.0);
535
536        let result = length / 2.0;
537
538        let expected: Length<f32, Cm> = Length::new(2.5);
539        assert_eq!(result, expected);
540    }
541
542    #[test]
543    fn test_division_assignment() {
544        let mut length: Length<f32, Mm> = Length::new(10.0);
545
546        length /= 2.0;
547
548        let expected: Length<f32, Mm> = Length::new(5.0);
549        assert_eq!(length, expected);
550    }
551
552    #[test]
553    fn test_negation() {
554        let length: Length<f32, Cm> = Length::new(5.0);
555
556        let result = -length;
557
558        let expected: Length<f32, Cm> = Length::new(-5.0);
559        assert_eq!(result, expected);
560    }
561
562    #[test]
563    fn test_cast() {
564        let length_as_i32: Length<i32, Cm> = Length::new(5);
565
566        let result: Length<f32, Cm> = length_as_i32.cast();
567
568        let length_as_f32: Length<f32, Cm> = Length::new(5.0);
569        assert_eq!(result, length_as_f32);
570    }
571
572    #[test]
573    fn test_equality() {
574        let length_5_point_0: Length<f32, Cm> = Length::new(5.0);
575        let length_5_point_1: Length<f32, Cm> = Length::new(5.1);
576        let length_0_point_1: Length<f32, Cm> = Length::new(0.1);
577
578        assert!(length_5_point_0 == length_5_point_1 - length_0_point_1);
579        assert!(length_5_point_0 != length_5_point_1);
580    }
581
582    #[test]
583    fn test_order() {
584        let length_5_point_0: Length<f32, Cm> = Length::new(5.0);
585        let length_5_point_1: Length<f32, Cm> = Length::new(5.1);
586        let length_0_point_1: Length<f32, Cm> = Length::new(0.1);
587
588        assert!(length_5_point_0 < length_5_point_1);
589        assert!(length_5_point_0 <= length_5_point_1);
590        assert!(length_5_point_0 <= length_5_point_1 - length_0_point_1);
591        assert!(length_5_point_1 > length_5_point_0);
592        assert!(length_5_point_1 >= length_5_point_0);
593        assert!(length_5_point_0 >= length_5_point_1 - length_0_point_1);
594    }
595
596    #[test]
597    fn test_zero_add() {
598        type LengthCm = Length<f32, Cm>;
599        let length: LengthCm = Length::new(5.0);
600
601        let result = length - LengthCm::zero();
602
603        assert_eq!(result, length);
604    }
605
606    #[test]
607    fn test_zero_division() {
608        type LengthCm = Length<f32, Cm>;
609        let length: LengthCm = Length::new(5.0);
610        let length_zero: LengthCm = Length::zero();
611
612        let result = length / length_zero;
613
614        let expected: Scale<f32, Cm, Cm> = Scale::new(INFINITY);
615        assert_eq!(result, expected);
616    }
617}