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