1use scale::TypedScale;
12use num::Zero;
13
14use num_traits::{NumCast, Saturating};
15use num::One;
16#[cfg(feature = "serde")]
17use serde::{Deserialize, Deserializer, Serialize, Serializer};
18use core::cmp::Ordering;
19use core::ops::{Add, Div, Mul, Neg, Sub};
20use core::ops::{AddAssign, DivAssign, MulAssign, SubAssign};
21use core::marker::PhantomData;
22use core::fmt;
23
24#[repr(C)]
38pub struct Length<T, Unit>(pub T, #[doc(hidden)] pub PhantomData<Unit>);
39
40impl<T: Clone, Unit> Clone for Length<T, Unit> {
41 fn clone(&self) -> Self {
42 Length(self.0.clone(), PhantomData)
43 }
44}
45
46impl<T: Copy, Unit> Copy for Length<T, Unit> {}
47
48#[cfg(feature = "serde")]
49impl<'de, Unit, T> Deserialize<'de> for Length<T, Unit>
50where
51 T: Deserialize<'de>,
52{
53 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
54 where
55 D: Deserializer<'de>,
56 {
57 Ok(Length(
58 try!(Deserialize::deserialize(deserializer)),
59 PhantomData,
60 ))
61 }
62}
63
64#[cfg(feature = "serde")]
65impl<T, Unit> Serialize for Length<T, Unit>
66where
67 T: Serialize,
68{
69 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
70 where
71 S: Serializer,
72 {
73 self.0.serialize(serializer)
74 }
75}
76
77impl<T, Unit> Length<T, Unit> {
78 pub fn new(x: T) -> Self {
79 Length(x, PhantomData)
80 }
81}
82
83impl<Unit, T: Clone> Length<T, Unit> {
84 pub fn get(&self) -> T {
85 self.0.clone()
86 }
87}
88
89impl<T: fmt::Debug + Clone, U> fmt::Debug for Length<T, U> {
90 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
91 self.get().fmt(f)
92 }
93}
94
95impl<T: fmt::Display + Clone, U> fmt::Display for Length<T, U> {
96 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
97 self.get().fmt(f)
98 }
99}
100
101impl<U, T: Clone + Add<T, Output = T>> Add for Length<T, U> {
103 type Output = Length<T, U>;
104 fn add(self, other: Length<T, U>) -> Length<T, U> {
105 Length::new(self.get() + other.get())
106 }
107}
108
109impl<U, T: Clone + AddAssign<T>> AddAssign for Length<T, U> {
111 fn add_assign(&mut self, other: Length<T, U>) {
112 self.0 += other.get();
113 }
114}
115
116impl<U, T: Clone + Sub<T, Output = T>> Sub<Length<T, U>> for Length<T, U> {
118 type Output = Length<T, U>;
119 fn sub(self, other: Length<T, U>) -> <Self as Sub>::Output {
120 Length::new(self.get() - other.get())
121 }
122}
123
124impl<U, T: Clone + SubAssign<T>> SubAssign for Length<T, U> {
126 fn sub_assign(&mut self, other: Length<T, U>) {
127 self.0 -= other.get();
128 }
129}
130
131impl<U, T: Clone + Saturating> Saturating for Length<T, U> {
133 fn saturating_add(self, other: Length<T, U>) -> Length<T, U> {
134 Length::new(self.get().saturating_add(other.get()))
135 }
136
137 fn saturating_sub(self, other: Length<T, U>) -> Length<T, U> {
138 Length::new(self.get().saturating_sub(other.get()))
139 }
140}
141
142impl<Src, Dst, T: Clone + Div<T, Output = T>> Div<Length<T, Src>> for Length<T, Dst> {
144 type Output = TypedScale<T, Src, Dst>;
145 #[inline]
146 fn div(self, other: Length<T, Src>) -> TypedScale<T, Src, Dst> {
147 TypedScale::new(self.get() / other.get())
148 }
149}
150
151impl<T: Copy + Mul<T, Output = T>, U> Mul<T> for Length<T, U> {
153 type Output = Self;
154 #[inline]
155 fn mul(self, scale: T) -> Self {
156 Length::new(self.get() * scale)
157 }
158}
159
160impl<T: Copy + Mul<T, Output = T>, U> MulAssign<T> for Length<T, U> {
162 #[inline]
163 fn mul_assign(&mut self, scale: T) {
164 *self = *self * scale
165 }
166}
167
168impl<T: Copy + Div<T, Output = T>, U> Div<T> for Length<T, U> {
170 type Output = Self;
171 #[inline]
172 fn div(self, scale: T) -> Self {
173 Length::new(self.get() / scale)
174 }
175}
176
177impl<T: Copy + Div<T, Output = T>, U> DivAssign<T> for Length<T, U> {
179 #[inline]
180 fn div_assign(&mut self, scale: T) {
181 *self = *self / scale
182 }
183}
184
185impl<Src, Dst, T: Clone + Mul<T, Output = T>> Mul<TypedScale<T, Src, Dst>> for Length<T, Src> {
187 type Output = Length<T, Dst>;
188 #[inline]
189 fn mul(self, scale: TypedScale<T, Src, Dst>) -> Length<T, Dst> {
190 Length::new(self.get() * scale.get())
191 }
192}
193
194impl<Src, Dst, T: Clone + Div<T, Output = T>> Div<TypedScale<T, Src, Dst>> for Length<T, Dst> {
196 type Output = Length<T, Src>;
197 #[inline]
198 fn div(self, scale: TypedScale<T, Src, Dst>) -> Length<T, Src> {
199 Length::new(self.get() / scale.get())
200 }
201}
202
203impl<U, T: Clone + Neg<Output = T>> Neg for Length<T, U> {
205 type Output = Length<T, U>;
206 #[inline]
207 fn neg(self) -> Length<T, U> {
208 Length::new(-self.get())
209 }
210}
211
212impl<Unit, T0: NumCast + Clone> Length<T0, Unit> {
213 pub fn cast<T1: NumCast + Clone>(&self) -> Length<T1, Unit> {
215 self.try_cast().unwrap()
216 }
217
218 pub fn try_cast<T1: NumCast + Clone>(&self) -> Option<Length<T1, Unit>> {
220 NumCast::from(self.get()).map(Length::new)
221 }
222}
223
224impl<Unit, T: Clone + PartialEq> PartialEq for Length<T, Unit> {
225 fn eq(&self, other: &Self) -> bool {
226 self.get().eq(&other.get())
227 }
228}
229
230impl<Unit, T: Clone + PartialOrd> PartialOrd for Length<T, Unit> {
231 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
232 self.get().partial_cmp(&other.get())
233 }
234}
235
236impl<Unit, T: Clone + Eq> Eq for Length<T, Unit> {}
237
238impl<Unit, T: Clone + Ord> Ord for Length<T, Unit> {
239 fn cmp(&self, other: &Self) -> Ordering {
240 self.get().cmp(&other.get())
241 }
242}
243
244impl<Unit, T: Zero> Zero for Length<T, Unit> {
245 fn zero() -> Self {
246 Length::new(Zero::zero())
247 }
248}
249
250impl<T, U> Length<T, U>
251where
252 T: Copy + One + Add<Output = T> + Sub<Output = T> + Mul<Output = T>,
253{
254 #[inline]
258 pub fn lerp(&self, other: Self, t: T) -> Self {
259 let one_t = T::one() - t;
260 Length::new(one_t * self.get() + t * other.get())
261 }
262}
263
264#[cfg(test)]
265mod tests {
266 use super::Length;
267 use num::Zero;
268
269 use num_traits::Saturating;
270 use scale::TypedScale;
271 use core::f32::INFINITY;
272
273 enum Inch {}
274 enum Mm {}
275 enum Cm {}
276 enum Second {}
277
278 #[cfg(feature = "serde")]
279 mod serde {
280 use super::*;
281
282 extern crate serde_test;
283 use self::serde_test::Token;
284 use self::serde_test::assert_tokens;
285
286 #[test]
287 fn test_length_serde() {
288 let one_cm: Length<f32, Mm> = Length::new(10.0);
289
290 assert_tokens(&one_cm, &[Token::F32(10.0)]);
291 }
292 }
293
294 #[test]
295 fn test_clone() {
296 let mut variable_length: Length<f32, Inch> = Length::new(12.0);
299
300 let one_foot = variable_length.clone();
301 variable_length.0 = 24.0;
302
303 assert_eq!(one_foot.get(), 12.0);
304 assert_eq!(variable_length.get(), 24.0);
305 }
306
307 #[test]
308 fn test_get_clones_length_value() {
309 let mut length: Length<Vec<i32>, Inch> = Length::new(vec![1, 2, 3]);
312
313 let value = length.get();
314 length.0.push(4);
315
316 assert_eq!(value, vec![1, 2, 3]);
317 assert_eq!(length.get(), vec![1, 2, 3, 4]);
318 }
319
320 #[test]
321 fn test_add() {
322 let length1: Length<u8, Mm> = Length::new(250);
323 let length2: Length<u8, Mm> = Length::new(5);
324
325 let result = length1 + length2;
326
327 assert_eq!(result.get(), 255);
328 }
329
330 #[test]
331 fn test_addassign() {
332 let one_cm: Length<f32, Mm> = Length::new(10.0);
333 let mut measurement: Length<f32, Mm> = Length::new(5.0);
334
335 measurement += one_cm;
336
337 assert_eq!(measurement.get(), 15.0);
338 }
339
340 #[test]
341 fn test_sub() {
342 let length1: Length<u8, Mm> = Length::new(250);
343 let length2: Length<u8, Mm> = Length::new(5);
344
345 let result = length1 - length2;
346
347 assert_eq!(result.get(), 245);
348 }
349
350 #[test]
351 fn test_subassign() {
352 let one_cm: Length<f32, Mm> = Length::new(10.0);
353 let mut measurement: Length<f32, Mm> = Length::new(5.0);
354
355 measurement -= one_cm;
356
357 assert_eq!(measurement.get(), -5.0);
358 }
359
360 #[test]
361 fn test_saturating_add() {
362 let length1: Length<u8, Mm> = Length::new(250);
363 let length2: Length<u8, Mm> = Length::new(6);
364
365 let result = length1.saturating_add(length2);
366
367 assert_eq!(result.get(), 255);
368 }
369
370 #[test]
371 fn test_saturating_sub() {
372 let length1: Length<u8, Mm> = Length::new(5);
373 let length2: Length<u8, Mm> = Length::new(10);
374
375 let result = length1.saturating_sub(length2);
376
377 assert_eq!(result.get(), 0);
378 }
379
380 #[test]
381 fn test_division_by_length() {
382 let length: Length<f32, Cm> = Length::new(5.0);
385 let duration: Length<f32, Second> = Length::new(10.0);
386
387 let result = length / duration;
388
389 let expected: TypedScale<f32, Second, Cm> = TypedScale::new(0.5);
390 assert_eq!(result, expected);
391 }
392
393 #[test]
394 fn test_multiplication() {
395 let length_mm: Length<f32, Mm> = Length::new(10.0);
396 let cm_per_mm: TypedScale<f32, Mm, Cm> = TypedScale::new(0.1);
397
398 let result = length_mm * cm_per_mm;
399
400 let expected: Length<f32, Cm> = Length::new(1.0);
401 assert_eq!(result, expected);
402 }
403
404 #[test]
405 fn test_multiplication_with_scalar() {
406 let length_mm: Length<f32, Mm> = Length::new(10.0);
407
408 let result = length_mm * 2.0;
409
410 let expected: Length<f32, Mm> = Length::new(20.0);
411 assert_eq!(result, expected);
412 }
413
414 #[test]
415 fn test_multiplication_assignment() {
416 let mut length: Length<f32, Mm> = Length::new(10.0);
417
418 length *= 2.0;
419
420 let expected: Length<f32, Mm> = Length::new(20.0);
421 assert_eq!(length, expected);
422 }
423
424 #[test]
425 fn test_division_by_scalefactor() {
426 let length: Length<f32, Cm> = Length::new(5.0);
427 let cm_per_second: TypedScale<f32, Second, Cm> = TypedScale::new(10.0);
428
429 let result = length / cm_per_second;
430
431 let expected: Length<f32, Second> = Length::new(0.5);
432 assert_eq!(result, expected);
433 }
434
435 #[test]
436 fn test_division_by_scalar() {
437 let length: Length<f32, Cm> = Length::new(5.0);
438
439 let result = length / 2.0;
440
441 let expected: Length<f32, Cm> = Length::new(2.5);
442 assert_eq!(result, expected);
443 }
444
445 #[test]
446 fn test_division_assignment() {
447 let mut length: Length<f32, Mm> = Length::new(10.0);
448
449 length /= 2.0;
450
451 let expected: Length<f32, Mm> = Length::new(5.0);
452 assert_eq!(length, expected);
453 }
454
455 #[test]
456 fn test_negation() {
457 let length: Length<f32, Cm> = Length::new(5.0);
458
459 let result = -length;
460
461 let expected: Length<f32, Cm> = Length::new(-5.0);
462 assert_eq!(result, expected);
463 }
464
465 #[test]
466 fn test_cast() {
467 let length_as_i32: Length<i32, Cm> = Length::new(5);
468
469 let result: Length<f32, Cm> = length_as_i32.cast();
470
471 let length_as_f32: Length<f32, Cm> = Length::new(5.0);
472 assert_eq!(result, length_as_f32);
473 }
474
475 #[test]
476 fn test_equality() {
477 let length_5_point_0: Length<f32, Cm> = Length::new(5.0);
478 let length_5_point_1: Length<f32, Cm> = Length::new(5.1);
479 let length_0_point_1: Length<f32, Cm> = Length::new(0.1);
480
481 assert!(length_5_point_0 == length_5_point_1 - length_0_point_1);
482 assert!(length_5_point_0 != length_5_point_1);
483 }
484
485 #[test]
486 fn test_order() {
487 let length_5_point_0: Length<f32, Cm> = Length::new(5.0);
488 let length_5_point_1: Length<f32, Cm> = Length::new(5.1);
489 let length_0_point_1: Length<f32, Cm> = Length::new(0.1);
490
491 assert!(length_5_point_0 < length_5_point_1);
492 assert!(length_5_point_0 <= length_5_point_1);
493 assert!(length_5_point_0 <= length_5_point_1 - length_0_point_1);
494 assert!(length_5_point_1 > length_5_point_0);
495 assert!(length_5_point_1 >= length_5_point_0);
496 assert!(length_5_point_0 >= length_5_point_1 - length_0_point_1);
497 }
498
499 #[test]
500 fn test_zero_add() {
501 type LengthCm = Length<f32, Cm>;
502 let length: LengthCm = Length::new(5.0);
503
504 let result = length - LengthCm::zero();
505
506 assert_eq!(result, length);
507 }
508
509 #[test]
510 fn test_zero_division() {
511 type LengthCm = Length<f32, Cm>;
512 let length: LengthCm = Length::new(5.0);
513 let length_zero: LengthCm = Length::zero();
514
515 let result = length / length_zero;
516
517 let expected: TypedScale<f32, Cm, Cm> = TypedScale::new(INFINITY);
518 assert_eq!(result, expected);
519 }
520}