1use 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};
26#[cfg(feature = "malloc_size_of")]
27use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
28use num_traits::{NumCast, Saturating};
29#[cfg(feature = "serde")]
30use serde::{Deserialize, Deserializer, Serialize, Serializer};
31
32#[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 = "arbitrary")]
81impl<'a, T, U> arbitrary::Arbitrary<'a> for Length<T, U>
82where
83 T: arbitrary::Arbitrary<'a>,
84{
85 fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
86 Ok(Length(arbitrary::Arbitrary::arbitrary(u)?, PhantomData))
87 }
88}
89
90#[cfg(feature = "bytemuck")]
91unsafe impl<T: Zeroable, U> Zeroable for Length<T, U> {}
92
93#[cfg(feature = "bytemuck")]
94unsafe impl<T: Pod, U: 'static> Pod for Length<T, U> {}
95
96#[cfg(feature = "malloc_size_of")]
97impl<T: MallocSizeOf, U> MallocSizeOf for Length<T, U> {
98 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
99 self.0.size_of(ops)
100 }
101}
102
103impl<T, U> Length<T, U> {
104 #[inline]
106 pub const fn new(x: T) -> Self {
107 Length(x, PhantomData)
108 }
109}
110
111impl<T: Clone, U> Length<T, U> {
112 pub fn get(self) -> T {
114 self.0
115 }
116
117 #[inline]
119 pub fn cast_unit<V>(self) -> Length<T, V> {
120 Length::new(self.0)
121 }
122
123 #[inline]
140 pub fn lerp(self, other: Self, t: T) -> Self
141 where
142 T: One + Sub<Output = T> + Mul<Output = T> + Add<Output = T>,
143 {
144 let one_t = T::one() - t.clone();
145 Length::new(one_t * self.0.clone() + t * other.0)
146 }
147}
148
149impl<T: PartialOrd, U> Length<T, U> {
150 #[inline]
152 pub fn min(self, other: Self) -> Self {
153 min(self, other)
154 }
155
156 #[inline]
158 pub fn max(self, other: Self) -> Self {
159 max(self, other)
160 }
161}
162
163impl<T: NumCast + Clone, U> Length<T, U> {
164 #[inline]
166 pub fn cast<NewT: NumCast>(self) -> Length<NewT, U> {
167 self.try_cast().unwrap()
168 }
169
170 pub fn try_cast<NewT: NumCast>(self) -> Option<Length<NewT, U>> {
172 NumCast::from(self.0).map(Length::new)
173 }
174}
175
176impl<T: fmt::Debug, U> fmt::Debug for Length<T, U> {
177 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
178 self.0.fmt(f)
179 }
180}
181
182impl<T: Default, U> Default for Length<T, U> {
183 #[inline]
184 fn default() -> Self {
185 Length::new(Default::default())
186 }
187}
188
189impl<T: Hash, U> Hash for Length<T, U> {
190 fn hash<H: Hasher>(&self, h: &mut H) {
191 self.0.hash(h);
192 }
193}
194
195impl<T: Add, U> Add 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
204impl<T: Add + Copy, U> Add<&Self> for Length<T, U> {
206 type Output = Length<T::Output, U>;
207
208 fn add(self, other: &Self) -> Self::Output {
209 Length::new(self.0 + other.0)
210 }
211}
212
213impl<T: Add<Output = T> + Zero, U> Sum for Length<T, U> {
215 fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
216 iter.fold(Self::zero(), Add::add)
217 }
218}
219
220impl<'a, T: 'a + Add<Output = T> + Copy + Zero, U: 'a> Sum<&'a Self> for Length<T, U> {
222 fn sum<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
223 iter.fold(Self::zero(), Add::add)
224 }
225}
226
227impl<T: AddAssign, U> AddAssign for Length<T, U> {
229 fn add_assign(&mut self, other: Self) {
230 self.0 += other.0;
231 }
232}
233
234impl<T: Sub, U> Sub for Length<T, U> {
236 type Output = Length<T::Output, U>;
237
238 fn sub(self, other: Length<T, U>) -> Self::Output {
239 Length::new(self.0 - other.0)
240 }
241}
242
243impl<T: SubAssign, U> SubAssign for Length<T, U> {
245 fn sub_assign(&mut self, other: Self) {
246 self.0 -= other.0;
247 }
248}
249
250impl<T: Saturating, U> Saturating for Length<T, U> {
252 fn saturating_add(self, other: Self) -> Self {
253 Length::new(self.0.saturating_add(other.0))
254 }
255
256 fn saturating_sub(self, other: Self) -> Self {
257 Length::new(self.0.saturating_sub(other.0))
258 }
259}
260
261impl<Src, Dst, T: Div> Div<Length<T, Src>> for Length<T, Dst> {
263 type Output = Scale<T::Output, Src, Dst>;
264
265 #[inline]
266 fn div(self, other: Length<T, Src>) -> Self::Output {
267 Scale::new(self.0 / other.0)
268 }
269}
270
271impl<T: Mul, U> Mul<T> for Length<T, U> {
273 type Output = Length<T::Output, U>;
274
275 #[inline]
276 fn mul(self, scale: T) -> Self::Output {
277 Length::new(self.0 * scale)
278 }
279}
280
281impl<T: Copy + Mul<T, Output = T>, U> MulAssign<T> for Length<T, U> {
283 #[inline]
284 fn mul_assign(&mut self, scale: T) {
285 *self = *self * scale;
286 }
287}
288
289impl<T: Div, U> Div<T> for Length<T, U> {
291 type Output = Length<T::Output, U>;
292
293 #[inline]
294 fn div(self, scale: T) -> Self::Output {
295 Length::new(self.0 / scale)
296 }
297}
298
299impl<T: Copy + Div<T, Output = T>, U> DivAssign<T> for Length<T, U> {
301 #[inline]
302 fn div_assign(&mut self, scale: T) {
303 *self = *self / scale;
304 }
305}
306
307impl<Src, Dst, T: Mul> Mul<Scale<T, Src, Dst>> for Length<T, Src> {
309 type Output = Length<T::Output, Dst>;
310
311 #[inline]
312 fn mul(self, scale: Scale<T, Src, Dst>) -> Self::Output {
313 Length::new(self.0 * scale.0)
314 }
315}
316
317impl<Src, Dst, T: Div> Div<Scale<T, Src, Dst>> for Length<T, Dst> {
319 type Output = Length<T::Output, Src>;
320
321 #[inline]
322 fn div(self, scale: Scale<T, Src, Dst>) -> Self::Output {
323 Length::new(self.0 / scale.0)
324 }
325}
326
327impl<U, T: Neg> Neg for Length<T, U> {
329 type Output = Length<T::Output, U>;
330
331 #[inline]
332 fn neg(self) -> Self::Output {
333 Length::new(-self.0)
334 }
335}
336
337impl<T: PartialEq, U> PartialEq for Length<T, U> {
338 fn eq(&self, other: &Self) -> bool {
339 self.0.eq(&other.0)
340 }
341}
342
343impl<T: PartialOrd, U> PartialOrd for Length<T, U> {
344 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
345 self.0.partial_cmp(&other.0)
346 }
347}
348
349impl<T: Eq, U> Eq for Length<T, U> {}
350
351impl<T: Ord, U> Ord for Length<T, U> {
352 fn cmp(&self, other: &Self) -> Ordering {
353 self.0.cmp(&other.0)
354 }
355}
356
357impl<T: Zero, U> Zero for Length<T, U> {
358 #[inline]
359 fn zero() -> Self {
360 Length::new(Zero::zero())
361 }
362}
363
364impl<U, T: ApproxEq<T>> ApproxEq<T> for Length<T, U> {
365 #[inline]
366 fn approx_epsilon() -> T {
367 T::approx_epsilon()
368 }
369
370 #[inline]
371 fn approx_eq_eps(&self, other: &Length<T, U>, approx_epsilon: &T) -> bool {
372 self.0.approx_eq_eps(&other.0, approx_epsilon)
373 }
374}
375
376#[cfg(test)]
377mod tests {
378 use super::Length;
379 use crate::num::Zero;
380
381 use crate::scale::Scale;
382 use core::f32::INFINITY;
383 use num_traits::Saturating;
384
385 enum Inch {}
386 enum Mm {}
387 enum Cm {}
388 enum Second {}
389
390 #[cfg(feature = "serde")]
391 mod serde {
392 use super::*;
393
394 extern crate serde_test;
395 use self::serde_test::assert_tokens;
396 use self::serde_test::Token;
397
398 #[test]
399 fn test_length_serde() {
400 let one_cm: Length<f32, Mm> = Length::new(10.0);
401
402 assert_tokens(&one_cm, &[Token::F32(10.0)]);
403 }
404 }
405
406 #[test]
407 fn test_clone() {
408 let mut variable_length: Length<f32, Inch> = Length::new(12.0);
411
412 let one_foot = variable_length.clone();
413 variable_length.0 = 24.0;
414
415 assert_eq!(one_foot.get(), 12.0);
416 assert_eq!(variable_length.get(), 24.0);
417 }
418
419 #[test]
420 fn test_add() {
421 let length1: Length<u8, Mm> = Length::new(250);
422 let length2: Length<u8, Mm> = Length::new(5);
423
424 assert_eq!((length1 + length2).get(), 255);
425 assert_eq!((length1 + &length2).get(), 255);
426 }
427
428 #[test]
429 fn test_sum() {
430 type L = Length<f32, Mm>;
431 let lengths = [L::new(1.0), L::new(2.0), L::new(3.0)];
432
433 assert_eq!(lengths.iter().sum::<L>(), L::new(6.0));
434 }
435
436 #[test]
437 fn test_addassign() {
438 let one_cm: Length<f32, Mm> = Length::new(10.0);
439 let mut measurement: Length<f32, Mm> = Length::new(5.0);
440
441 measurement += one_cm;
442
443 assert_eq!(measurement.get(), 15.0);
444 }
445
446 #[test]
447 fn test_sub() {
448 let length1: Length<u8, Mm> = Length::new(250);
449 let length2: Length<u8, Mm> = Length::new(5);
450
451 let result = length1 - length2;
452
453 assert_eq!(result.get(), 245);
454 }
455
456 #[test]
457 fn test_subassign() {
458 let one_cm: Length<f32, Mm> = Length::new(10.0);
459 let mut measurement: Length<f32, Mm> = Length::new(5.0);
460
461 measurement -= one_cm;
462
463 assert_eq!(measurement.get(), -5.0);
464 }
465
466 #[test]
467 fn test_saturating_add() {
468 let length1: Length<u8, Mm> = Length::new(250);
469 let length2: Length<u8, Mm> = Length::new(6);
470
471 let result = length1.saturating_add(length2);
472
473 assert_eq!(result.get(), 255);
474 }
475
476 #[test]
477 fn test_saturating_sub() {
478 let length1: Length<u8, Mm> = Length::new(5);
479 let length2: Length<u8, Mm> = Length::new(10);
480
481 let result = length1.saturating_sub(length2);
482
483 assert_eq!(result.get(), 0);
484 }
485
486 #[test]
487 fn test_division_by_length() {
488 let length: Length<f32, Cm> = Length::new(5.0);
491 let duration: Length<f32, Second> = Length::new(10.0);
492
493 let result = length / duration;
494
495 let expected: Scale<f32, Second, Cm> = Scale::new(0.5);
496 assert_eq!(result, expected);
497 }
498
499 #[test]
500 fn test_multiplication() {
501 let length_mm: Length<f32, Mm> = Length::new(10.0);
502 let cm_per_mm: Scale<f32, Mm, Cm> = Scale::new(0.1);
503
504 let result = length_mm * cm_per_mm;
505
506 let expected: Length<f32, Cm> = Length::new(1.0);
507 assert_eq!(result, expected);
508 }
509
510 #[test]
511 fn test_multiplication_with_scalar() {
512 let length_mm: Length<f32, Mm> = Length::new(10.0);
513
514 let result = length_mm * 2.0;
515
516 let expected: Length<f32, Mm> = Length::new(20.0);
517 assert_eq!(result, expected);
518 }
519
520 #[test]
521 fn test_multiplication_assignment() {
522 let mut length: Length<f32, Mm> = Length::new(10.0);
523
524 length *= 2.0;
525
526 let expected: Length<f32, Mm> = Length::new(20.0);
527 assert_eq!(length, expected);
528 }
529
530 #[test]
531 fn test_division_by_scalefactor() {
532 let length: Length<f32, Cm> = Length::new(5.0);
533 let cm_per_second: Scale<f32, Second, Cm> = Scale::new(10.0);
534
535 let result = length / cm_per_second;
536
537 let expected: Length<f32, Second> = Length::new(0.5);
538 assert_eq!(result, expected);
539 }
540
541 #[test]
542 fn test_division_by_scalar() {
543 let length: Length<f32, Cm> = Length::new(5.0);
544
545 let result = length / 2.0;
546
547 let expected: Length<f32, Cm> = Length::new(2.5);
548 assert_eq!(result, expected);
549 }
550
551 #[test]
552 fn test_division_assignment() {
553 let mut length: Length<f32, Mm> = Length::new(10.0);
554
555 length /= 2.0;
556
557 let expected: Length<f32, Mm> = Length::new(5.0);
558 assert_eq!(length, expected);
559 }
560
561 #[test]
562 fn test_negation() {
563 let length: Length<f32, Cm> = Length::new(5.0);
564
565 let result = -length;
566
567 let expected: Length<f32, Cm> = Length::new(-5.0);
568 assert_eq!(result, expected);
569 }
570
571 #[test]
572 fn test_cast() {
573 let length_as_i32: Length<i32, Cm> = Length::new(5);
574
575 let result: Length<f32, Cm> = length_as_i32.cast();
576
577 let length_as_f32: Length<f32, Cm> = Length::new(5.0);
578 assert_eq!(result, length_as_f32);
579 }
580
581 #[test]
582 fn test_equality() {
583 let length_5_point_0: Length<f32, Cm> = Length::new(5.0);
584 let length_5_point_1: Length<f32, Cm> = Length::new(5.1);
585 let length_0_point_1: Length<f32, Cm> = Length::new(0.1);
586
587 assert!(length_5_point_0 == length_5_point_1 - length_0_point_1);
588 assert!(length_5_point_0 != length_5_point_1);
589 }
590
591 #[test]
592 fn test_order() {
593 let length_5_point_0: Length<f32, Cm> = Length::new(5.0);
594 let length_5_point_1: Length<f32, Cm> = Length::new(5.1);
595 let length_0_point_1: Length<f32, Cm> = Length::new(0.1);
596
597 assert!(length_5_point_0 < length_5_point_1);
598 assert!(length_5_point_0 <= length_5_point_1);
599 assert!(length_5_point_0 <= length_5_point_1 - length_0_point_1);
600 assert!(length_5_point_1 > length_5_point_0);
601 assert!(length_5_point_1 >= length_5_point_0);
602 assert!(length_5_point_0 >= length_5_point_1 - length_0_point_1);
603 }
604
605 #[test]
606 fn test_zero_add() {
607 type LengthCm = Length<f32, Cm>;
608 let length: LengthCm = Length::new(5.0);
609
610 let result = length - LengthCm::zero();
611
612 assert_eq!(result, length);
613 }
614
615 #[test]
616 fn test_zero_division() {
617 type LengthCm = Length<f32, Cm>;
618 let length: LengthCm = Length::new(5.0);
619 let length_zero: LengthCm = Length::zero();
620
621 let result = length / length_zero;
622
623 let expected: Scale<f32, Cm, Cm> = Scale::new(INFINITY);
624 assert_eq!(result, expected);
625 }
626}