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