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