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