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 
11 use scale::Scale;
12 use num::Zero;
13 
14 use num_traits::{NumCast, Saturating};
15 use num::One;
16 #[cfg(feature = "serde")]
17 use serde::{Deserialize, Deserializer, Serialize, Serializer};
18 use core::cmp::Ordering;
19 use core::ops::{Add, Div, Mul, Neg, Sub};
20 use core::ops::{AddAssign, DivAssign, MulAssign, SubAssign};
21 use core::hash::{Hash, Hasher};
22 use core::marker::PhantomData;
23 use core::fmt;
24 
25 /// A one-dimensional distance, with value represented by `T` and unit of measurement `Unit`.
26 ///
27 /// `T` can be any numeric type, for example a primitive type like `u64` or `f32`.
28 ///
29 /// `Unit` is not used in the representation of a `Length` value. It is used only at compile time
30 /// to ensure that a `Length` stored with one unit is converted explicitly before being used in an
31 /// expression that requires a different unit.  It may be a type without values, such as an empty
32 /// enum.
33 ///
34 /// You can multiply a `Length` by a `scale::Scale` to convert it from one unit to
35 /// another. See the [`Scale`] docs for an example.
36 ///
37 /// [`Scale`]: struct.Scale.html
38 #[repr(C)]
39 pub struct Length<T, Unit>(pub T, #[doc(hidden)] pub PhantomData<Unit>);
40 
41 impl<T: Clone, U> Clone for Length<T, U> {
clone(&self) -> Self42     fn clone(&self) -> Self {
43         Length(self.0.clone(), PhantomData)
44     }
45 }
46 
47 impl<T: Copy, U> Copy for Length<T, U> {}
48 
49 #[cfg(feature = "serde")]
50 impl<'de, T, U> Deserialize<'de> for Length<T, U>
51 where
52     T: Deserialize<'de>,
53 {
deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de>,54     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
55     where
56         D: Deserializer<'de>,
57     {
58         Ok(Length(
59             Deserialize::deserialize(deserializer)?,
60             PhantomData,
61         ))
62     }
63 }
64 
65 #[cfg(feature = "serde")]
66 impl<T, U> Serialize for Length<T, U>
67 where
68     T: Serialize,
69 {
serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,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 impl<T, U> Length<T, U> {
79     #[inline]
new(x: T) -> Self80     pub const fn new(x: T) -> Self {
81         Length(x, PhantomData)
82     }
83 }
84 
85 impl<T: Clone, U> Length<T, U> {
get(&self) -> T86     pub fn get(&self) -> T {
87         self.0.clone()
88     }
89 
90     /// Cast the unit
91     #[inline]
cast_unit<V>(&self) -> Length<T, V>92     pub fn cast_unit<V>(&self) -> Length<T, V> {
93         Length::new(self.0.clone())
94     }
95 }
96 
97 impl<T: fmt::Debug, U> fmt::Debug for Length<T, U> {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result98     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
99         self.0.fmt(f)
100     }
101 }
102 
103 impl<T: fmt::Display, U> fmt::Display for Length<T, U> {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result104     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
105         self.0.fmt(f)
106     }
107 }
108 
109 impl<T: Default, U> Default for Length<T, U> {
110     #[inline]
default() -> Self111     fn default() -> Self {
112         Length::new(Default::default())
113     }
114 }
115 
116 impl<T, U> Hash for Length<T, U>
117     where T: Hash
118 {
hash<H: Hasher>(&self, h: &mut H)119     fn hash<H: Hasher>(&self, h: &mut H) {
120         self.0.hash(h);
121     }
122 }
123 
124 // length + length
125 impl<U, T: Add<T, Output = T>> Add for Length<T, U> {
126     type Output = Length<T, U>;
add(self, other: Length<T, U>) -> Length<T, U>127     fn add(self, other: Length<T, U>) -> Length<T, U> {
128         Length::new(self.0 + other.0)
129     }
130 }
131 
132 // length += length
133 impl<U, T: AddAssign<T>> AddAssign for Length<T, U> {
add_assign(&mut self, other: Length<T, U>)134     fn add_assign(&mut self, other: Length<T, U>) {
135         self.0 += other.0;
136     }
137 }
138 
139 // length - length
140 impl<U, T: Sub<T, Output = T>> Sub<Length<T, U>> for Length<T, U> {
141     type Output = Length<T, U>;
sub(self, other: Length<T, U>) -> <Self as Sub>::Output142     fn sub(self, other: Length<T, U>) -> <Self as Sub>::Output {
143         Length::new(self.0 - other.0)
144     }
145 }
146 
147 // length -= length
148 impl<U, T: SubAssign<T>> SubAssign for Length<T, U> {
sub_assign(&mut self, other: Length<T, U>)149     fn sub_assign(&mut self, other: Length<T, U>) {
150         self.0 -= other.0;
151     }
152 }
153 
154 // Saturating length + length and length - length.
155 impl<U, T: Saturating> Saturating for Length<T, U> {
saturating_add(self, other: Length<T, U>) -> Length<T, U>156     fn saturating_add(self, other: Length<T, U>) -> Length<T, U> {
157         Length::new(self.0.saturating_add(other.0))
158     }
159 
saturating_sub(self, other: Length<T, U>) -> Length<T, U>160     fn saturating_sub(self, other: Length<T, U>) -> Length<T, U> {
161         Length::new(self.0.saturating_sub(other.0))
162     }
163 }
164 
165 // length / length
166 impl<Src, Dst, T: Div<T, Output = T>> Div<Length<T, Src>> for Length<T, Dst> {
167     type Output = Scale<T, Src, Dst>;
168     #[inline]
div(self, other: Length<T, Src>) -> Scale<T, Src, Dst>169     fn div(self, other: Length<T, Src>) -> Scale<T, Src, Dst> {
170         Scale::new(self.0 / other.0)
171     }
172 }
173 
174 // length * scalar
175 impl<T: Mul<T, Output = T>, U> Mul<T> for Length<T, U> {
176     type Output = Self;
177     #[inline]
mul(self, scale: T) -> Self178     fn mul(self, scale: T) -> Self {
179         Length::new(self.0 * scale)
180     }
181 }
182 
183 // length *= scalar
184 impl<T: Copy + Mul<T, Output = T>, U> MulAssign<T> for Length<T, U> {
185     #[inline]
mul_assign(&mut self, scale: T)186     fn mul_assign(&mut self, scale: T) {
187         *self = *self * scale
188     }
189 }
190 
191 // length / scalar
192 impl<T: Div<T, Output = T>, U> Div<T> for Length<T, U> {
193     type Output = Self;
194     #[inline]
div(self, scale: T) -> Self195     fn div(self, scale: T) -> Self {
196         Length::new(self.0 / scale)
197     }
198 }
199 
200 // length /= scalar
201 impl<T: Copy + Div<T, Output = T>, U> DivAssign<T> for Length<T, U> {
202     #[inline]
div_assign(&mut self, scale: T)203     fn div_assign(&mut self, scale: T) {
204         *self = *self / scale
205     }
206 }
207 
208 // length * scaleFactor
209 impl<Src, Dst, T: Mul<T, Output = T>> Mul<Scale<T, Src, Dst>> for Length<T, Src> {
210     type Output = Length<T, Dst>;
211     #[inline]
mul(self, scale: Scale<T, Src, Dst>) -> Length<T, Dst>212     fn mul(self, scale: Scale<T, Src, Dst>) -> Length<T, Dst> {
213         Length::new(self.0 * scale.0)
214     }
215 }
216 
217 // length / scaleFactor
218 impl<Src, Dst, T: Div<T, Output = T>> Div<Scale<T, Src, Dst>> for Length<T, Dst> {
219     type Output = Length<T, Src>;
220     #[inline]
div(self, scale: Scale<T, Src, Dst>) -> Length<T, Src>221     fn div(self, scale: Scale<T, Src, Dst>) -> Length<T, Src> {
222         Length::new(self.0 / scale.0)
223     }
224 }
225 
226 // -length
227 impl<U, T: Neg<Output = T>> Neg for Length<T, U> {
228     type Output = Length<T, U>;
229     #[inline]
neg(self) -> Length<T, U>230     fn neg(self) -> Length<T, U> {
231         Length::new(-self.0)
232     }
233 }
234 
235 impl<T: NumCast + Clone, U> Length<T, U> {
236     /// Cast from one numeric representation to another, preserving the units.
237     #[inline]
cast<NewT: NumCast>(&self) -> Length<NewT, U>238     pub fn cast<NewT: NumCast>(&self) -> Length<NewT, U> {
239         self.try_cast().unwrap()
240     }
241 
242     /// Fallible cast from one numeric representation to another, preserving the units.
try_cast<NewT: NumCast>(&self) -> Option<Length<NewT, U>>243     pub fn try_cast<NewT: NumCast>(&self) -> Option<Length<NewT, U>> {
244         NumCast::from(self.get()).map(Length::new)
245     }
246 }
247 
248 impl<T: PartialEq, U> PartialEq for Length<T, U> {
eq(&self, other: &Self) -> bool249     fn eq(&self, other: &Self) -> bool {
250         self.0.eq(&other.0)
251     }
252 }
253 
254 impl<T: PartialOrd, U> PartialOrd for Length<T, U> {
partial_cmp(&self, other: &Self) -> Option<Ordering>255     fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
256         self.0.partial_cmp(&other.0)
257     }
258 }
259 
260 impl<T: Eq, U> Eq for Length<T, U> {}
261 
262 impl<T: Ord, U> Ord for Length<T, U> {
cmp(&self, other: &Self) -> Ordering263     fn cmp(&self, other: &Self) -> Ordering {
264         self.0.cmp(&other.0)
265     }
266 }
267 
268 impl<T: Zero, U> Zero for Length<T, U> {
269     #[inline]
zero() -> Self270     fn zero() -> Self {
271         Length::new(Zero::zero())
272     }
273 }
274 
275 impl<T, U> Length<T, U>
276 where
277     T: Copy + One + Add<Output = T> + Sub<Output = T> + Mul<Output = T>,
278 {
279     /// Linearly interpolate between this length and another length.
280     ///
281     /// When `t` is `One::one()`, returned value equals to `other`,
282     /// otherwise equals to `self`.
283     #[inline]
lerp(&self, other: Self, t: T) -> Self284     pub fn lerp(&self, other: Self, t: T) -> Self {
285         let one_t = T::one() - t;
286         Length::new(one_t * self.get() + t * other.get())
287     }
288 }
289 
290 #[cfg(test)]
291 mod tests {
292     use super::Length;
293     use num::Zero;
294 
295     use num_traits::Saturating;
296     use scale::Scale;
297     use core::f32::INFINITY;
298 
299     enum Inch {}
300     enum Mm {}
301     enum Cm {}
302     enum Second {}
303 
304     #[cfg(feature = "serde")]
305     mod serde {
306         use super::*;
307 
308         extern crate serde_test;
309         use self::serde_test::Token;
310         use self::serde_test::assert_tokens;
311 
312         #[test]
test_length_serde()313         fn test_length_serde() {
314             let one_cm: Length<f32, Mm> = Length::new(10.0);
315 
316             assert_tokens(&one_cm, &[Token::F32(10.0)]);
317         }
318     }
319 
320     #[test]
test_clone()321     fn test_clone() {
322         // A cloned Length is a separate length with the state matching the
323         // original Length at the point it was cloned.
324         let mut variable_length: Length<f32, Inch> = Length::new(12.0);
325 
326         let one_foot = variable_length.clone();
327         variable_length.0 = 24.0;
328 
329         assert_eq!(one_foot.get(), 12.0);
330         assert_eq!(variable_length.get(), 24.0);
331     }
332 
333     #[test]
test_get_clones_length_value()334     fn test_get_clones_length_value() {
335         // Calling get returns a clone of the Length's value.
336         // To test this, we need something clone-able - hence a vector.
337         let mut length: Length<Vec<i32>, Inch> = Length::new(vec![1, 2, 3]);
338 
339         let value = length.get();
340         length.0.push(4);
341 
342         assert_eq!(value, vec![1, 2, 3]);
343         assert_eq!(length.get(), vec![1, 2, 3, 4]);
344     }
345 
346     #[test]
test_add()347     fn test_add() {
348         let length1: Length<u8, Mm> = Length::new(250);
349         let length2: Length<u8, Mm> = Length::new(5);
350 
351         let result = length1 + length2;
352 
353         assert_eq!(result.get(), 255);
354     }
355 
356     #[test]
test_addassign()357     fn test_addassign() {
358         let one_cm: Length<f32, Mm> = Length::new(10.0);
359         let mut measurement: Length<f32, Mm> = Length::new(5.0);
360 
361         measurement += one_cm;
362 
363         assert_eq!(measurement.get(), 15.0);
364     }
365 
366     #[test]
test_sub()367     fn test_sub() {
368         let length1: Length<u8, Mm> = Length::new(250);
369         let length2: Length<u8, Mm> = Length::new(5);
370 
371         let result = length1 - length2;
372 
373         assert_eq!(result.get(), 245);
374     }
375 
376     #[test]
test_subassign()377     fn test_subassign() {
378         let one_cm: Length<f32, Mm> = Length::new(10.0);
379         let mut measurement: Length<f32, Mm> = Length::new(5.0);
380 
381         measurement -= one_cm;
382 
383         assert_eq!(measurement.get(), -5.0);
384     }
385 
386     #[test]
test_saturating_add()387     fn test_saturating_add() {
388         let length1: Length<u8, Mm> = Length::new(250);
389         let length2: Length<u8, Mm> = Length::new(6);
390 
391         let result = length1.saturating_add(length2);
392 
393         assert_eq!(result.get(), 255);
394     }
395 
396     #[test]
test_saturating_sub()397     fn test_saturating_sub() {
398         let length1: Length<u8, Mm> = Length::new(5);
399         let length2: Length<u8, Mm> = Length::new(10);
400 
401         let result = length1.saturating_sub(length2);
402 
403         assert_eq!(result.get(), 0);
404     }
405 
406     #[test]
test_division_by_length()407     fn test_division_by_length() {
408         // Division results in a Scale from denominator units
409         // to numerator units.
410         let length: Length<f32, Cm> = Length::new(5.0);
411         let duration: Length<f32, Second> = Length::new(10.0);
412 
413         let result = length / duration;
414 
415         let expected: Scale<f32, Second, Cm> = Scale::new(0.5);
416         assert_eq!(result, expected);
417     }
418 
419     #[test]
test_multiplication()420     fn test_multiplication() {
421         let length_mm: Length<f32, Mm> = Length::new(10.0);
422         let cm_per_mm: Scale<f32, Mm, Cm> = Scale::new(0.1);
423 
424         let result = length_mm * cm_per_mm;
425 
426         let expected: Length<f32, Cm> = Length::new(1.0);
427         assert_eq!(result, expected);
428     }
429 
430     #[test]
test_multiplication_with_scalar()431     fn test_multiplication_with_scalar() {
432         let length_mm: Length<f32, Mm> = Length::new(10.0);
433 
434         let result = length_mm * 2.0;
435 
436         let expected: Length<f32, Mm> = Length::new(20.0);
437         assert_eq!(result, expected);
438     }
439 
440     #[test]
test_multiplication_assignment()441     fn test_multiplication_assignment() {
442         let mut length: Length<f32, Mm> = Length::new(10.0);
443 
444         length *= 2.0;
445 
446         let expected: Length<f32, Mm> = Length::new(20.0);
447         assert_eq!(length, expected);
448     }
449 
450     #[test]
test_division_by_scalefactor()451     fn test_division_by_scalefactor() {
452         let length: Length<f32, Cm> = Length::new(5.0);
453         let cm_per_second: Scale<f32, Second, Cm> = Scale::new(10.0);
454 
455         let result = length / cm_per_second;
456 
457         let expected: Length<f32, Second> = Length::new(0.5);
458         assert_eq!(result, expected);
459     }
460 
461     #[test]
test_division_by_scalar()462     fn test_division_by_scalar() {
463         let length: Length<f32, Cm> = Length::new(5.0);
464 
465         let result = length / 2.0;
466 
467         let expected: Length<f32, Cm> = Length::new(2.5);
468         assert_eq!(result, expected);
469     }
470 
471     #[test]
test_division_assignment()472     fn test_division_assignment() {
473         let mut length: Length<f32, Mm> = Length::new(10.0);
474 
475         length /= 2.0;
476 
477         let expected: Length<f32, Mm> = Length::new(5.0);
478         assert_eq!(length, expected);
479     }
480 
481     #[test]
test_negation()482     fn test_negation() {
483         let length: Length<f32, Cm> = Length::new(5.0);
484 
485         let result = -length;
486 
487         let expected: Length<f32, Cm> = Length::new(-5.0);
488         assert_eq!(result, expected);
489     }
490 
491     #[test]
test_cast()492     fn test_cast() {
493         let length_as_i32: Length<i32, Cm> = Length::new(5);
494 
495         let result: Length<f32, Cm> = length_as_i32.cast();
496 
497         let length_as_f32: Length<f32, Cm> = Length::new(5.0);
498         assert_eq!(result, length_as_f32);
499     }
500 
501     #[test]
test_equality()502     fn test_equality() {
503         let length_5_point_0: Length<f32, Cm> = Length::new(5.0);
504         let length_5_point_1: Length<f32, Cm> = Length::new(5.1);
505         let length_0_point_1: Length<f32, Cm> = Length::new(0.1);
506 
507         assert!(length_5_point_0 == length_5_point_1 - length_0_point_1);
508         assert!(length_5_point_0 != length_5_point_1);
509     }
510 
511     #[test]
test_order()512     fn test_order() {
513         let length_5_point_0: Length<f32, Cm> = Length::new(5.0);
514         let length_5_point_1: Length<f32, Cm> = Length::new(5.1);
515         let length_0_point_1: Length<f32, Cm> = Length::new(0.1);
516 
517         assert!(length_5_point_0 < length_5_point_1);
518         assert!(length_5_point_0 <= length_5_point_1);
519         assert!(length_5_point_0 <= length_5_point_1 - length_0_point_1);
520         assert!(length_5_point_1 > length_5_point_0);
521         assert!(length_5_point_1 >= length_5_point_0);
522         assert!(length_5_point_0 >= length_5_point_1 - length_0_point_1);
523     }
524 
525     #[test]
test_zero_add()526     fn test_zero_add() {
527         type LengthCm = Length<f32, Cm>;
528         let length: LengthCm = Length::new(5.0);
529 
530         let result = length - LengthCm::zero();
531 
532         assert_eq!(result, length);
533     }
534 
535     #[test]
test_zero_division()536     fn test_zero_division() {
537         type LengthCm = Length<f32, Cm>;
538         let length: LengthCm = Length::new(5.0);
539         let length_zero: LengthCm = Length::zero();
540 
541         let result = length / length_zero;
542 
543         let expected: Scale<f32, Cm, Cm> = Scale::new(INFINITY);
544         assert_eq!(result, expected);
545     }
546 }
547