1use super::UnknownUnit;
11use crate::approxord::{max, min};
12use crate::length::Length;
13use crate::num::*;
14use crate::scale::Scale;
15use crate::vector::{vec2, BoolVector2D, Vector2D};
16use crate::vector::{vec3, BoolVector3D, Vector3D};
17
18use core::cmp::{Eq, PartialEq};
19use core::fmt;
20use core::hash::Hash;
21use core::iter::Sum;
22use core::marker::PhantomData;
23use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
24
25#[cfg(feature = "bytemuck")]
26use bytemuck::{Pod, Zeroable};
27#[cfg(feature = "mint")]
28use mint;
29use num_traits::{Float, NumCast, Signed};
30#[cfg(feature = "serde")]
31use serde;
32
33#[repr(C)]
35pub struct Size2D<T, U> {
36 pub width: T,
38 pub height: T,
40 #[doc(hidden)]
41 pub _unit: PhantomData<U>,
42}
43
44impl<T: Copy, U> Copy for Size2D<T, U> {}
45
46impl<T: Clone, U> Clone for Size2D<T, U> {
47 fn clone(&self) -> Self {
48 Size2D {
49 width: self.width.clone(),
50 height: self.height.clone(),
51 _unit: PhantomData,
52 }
53 }
54}
55
56#[cfg(feature = "serde")]
57impl<'de, T, U> serde::Deserialize<'de> for Size2D<T, U>
58where
59 T: serde::Deserialize<'de>,
60{
61 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
63 where
64 D: serde::Deserializer<'de>,
65 {
66 let (width, height) = serde::Deserialize::deserialize(deserializer)?;
67 Ok(Size2D {
68 width,
69 height,
70 _unit: PhantomData,
71 })
72 }
73}
74
75#[cfg(feature = "serde")]
76impl<T, U> serde::Serialize for Size2D<T, U>
77where
78 T: serde::Serialize,
79{
80 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
82 where
83 S: serde::Serializer,
84 {
85 (&self.width, &self.height).serialize(serializer)
86 }
87}
88
89#[cfg(feature = "arbitrary")]
90impl<'a, T, U> arbitrary::Arbitrary<'a> for Size2D<T, U>
91where
92 T: arbitrary::Arbitrary<'a>,
93{
94 fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
95 let (width, height) = arbitrary::Arbitrary::arbitrary(u)?;
96 Ok(Size2D {
97 width,
98 height,
99 _unit: PhantomData,
100 })
101 }
102}
103
104#[cfg(feature = "bytemuck")]
105unsafe impl<T: Zeroable, U> Zeroable for Size2D<T, U> {}
106
107#[cfg(feature = "bytemuck")]
108unsafe impl<T: Pod, U: 'static> Pod for Size2D<T, U> {}
109
110impl<T, U> Eq for Size2D<T, U> where T: Eq {}
111
112impl<T, U> PartialEq for Size2D<T, U>
113where
114 T: PartialEq,
115{
116 fn eq(&self, other: &Self) -> bool {
117 self.width == other.width && self.height == other.height
118 }
119}
120
121impl<T, U> Hash for Size2D<T, U>
122where
123 T: Hash,
124{
125 fn hash<H: core::hash::Hasher>(&self, h: &mut H) {
126 self.width.hash(h);
127 self.height.hash(h);
128 }
129}
130
131impl<T: fmt::Debug, U> fmt::Debug for Size2D<T, U> {
132 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
133 fmt::Debug::fmt(&self.width, f)?;
134 write!(f, "x")?;
135 fmt::Debug::fmt(&self.height, f)
136 }
137}
138
139impl<T: Default, U> Default for Size2D<T, U> {
140 fn default() -> Self {
141 Size2D::new(Default::default(), Default::default())
142 }
143}
144
145impl<T, U> Size2D<T, U> {
146 #[inline]
150 pub fn zero() -> Self
151 where
152 T: Zero,
153 {
154 Size2D::new(Zero::zero(), Zero::zero())
155 }
156
157 #[inline]
159 pub const fn new(width: T, height: T) -> Self {
160 Size2D {
161 width,
162 height,
163 _unit: PhantomData,
164 }
165 }
166 #[inline]
168 pub fn from_lengths(width: Length<T, U>, height: Length<T, U>) -> Self {
169 Size2D::new(width.0, height.0)
170 }
171
172 #[inline]
174 pub fn splat(v: T) -> Self
175 where
176 T: Clone,
177 {
178 Size2D {
179 width: v.clone(),
180 height: v,
181 _unit: PhantomData,
182 }
183 }
184
185 #[inline]
187 pub fn from_untyped(p: Size2D<T, UnknownUnit>) -> Self {
188 Size2D::new(p.width, p.height)
189 }
190}
191
192impl<T: Copy, U> Size2D<T, U> {
193 #[inline]
195 pub fn to_array(self) -> [T; 2] {
196 [self.width, self.height]
197 }
198
199 #[inline]
201 pub fn to_tuple(self) -> (T, T) {
202 (self.width, self.height)
203 }
204
205 #[inline]
207 pub fn to_vector(self) -> Vector2D<T, U> {
208 vec2(self.width, self.height)
209 }
210
211 #[inline]
213 pub fn to_untyped(self) -> Size2D<T, UnknownUnit> {
214 self.cast_unit()
215 }
216
217 #[inline]
219 pub fn cast_unit<V>(self) -> Size2D<T, V> {
220 Size2D::new(self.width, self.height)
221 }
222
223 #[inline]
234 #[must_use]
235 pub fn round(self) -> Self
236 where
237 T: Round,
238 {
239 Size2D::new(self.width.round(), self.height.round())
240 }
241
242 #[inline]
253 #[must_use]
254 pub fn ceil(self) -> Self
255 where
256 T: Ceil,
257 {
258 Size2D::new(self.width.ceil(), self.height.ceil())
259 }
260
261 #[inline]
272 #[must_use]
273 pub fn floor(self) -> Self
274 where
275 T: Floor,
276 {
277 Size2D::new(self.width.floor(), self.height.floor())
278 }
279
280 pub fn area(self) -> T::Output
282 where
283 T: Mul,
284 {
285 self.width * self.height
286 }
287
288 #[inline]
306 pub fn lerp(self, other: Self, t: T) -> Self
307 where
308 T: One + Sub<Output = T> + Mul<Output = T> + Add<Output = T>,
309 {
310 let one_t = T::one() - t;
311 self * one_t + other * t
312 }
313}
314
315impl<T: NumCast + Copy, U> Size2D<T, U> {
316 #[inline]
322 pub fn cast<NewT: NumCast>(self) -> Size2D<NewT, U> {
323 self.try_cast().unwrap()
324 }
325
326 pub fn try_cast<NewT: NumCast>(self) -> Option<Size2D<NewT, U>> {
332 match (NumCast::from(self.width), NumCast::from(self.height)) {
333 (Some(w), Some(h)) => Some(Size2D::new(w, h)),
334 _ => None,
335 }
336 }
337
338 #[inline]
342 pub fn to_f32(self) -> Size2D<f32, U> {
343 self.cast()
344 }
345
346 #[inline]
348 pub fn to_f64(self) -> Size2D<f64, U> {
349 self.cast()
350 }
351
352 #[inline]
358 pub fn to_usize(self) -> Size2D<usize, U> {
359 self.cast()
360 }
361
362 #[inline]
368 pub fn to_u32(self) -> Size2D<u32, U> {
369 self.cast()
370 }
371
372 #[inline]
378 pub fn to_u64(self) -> Size2D<u64, U> {
379 self.cast()
380 }
381
382 #[inline]
388 pub fn to_i32(self) -> Size2D<i32, U> {
389 self.cast()
390 }
391
392 #[inline]
398 pub fn to_i64(self) -> Size2D<i64, U> {
399 self.cast()
400 }
401}
402
403impl<T: Float, U> Size2D<T, U> {
404 #[inline]
406 pub fn is_finite(self) -> bool {
407 self.width.is_finite() && self.height.is_finite()
408 }
409}
410
411impl<T: Signed, U> Size2D<T, U> {
412 pub fn abs(self) -> Self {
418 size2(self.width.abs(), self.height.abs())
419 }
420
421 pub fn is_positive(self) -> bool {
423 self.width.is_positive() && self.height.is_positive()
424 }
425}
426
427impl<T: PartialOrd, U> Size2D<T, U> {
428 #[inline]
430 pub fn min(self, other: Self) -> Self {
431 size2(min(self.width, other.width), min(self.height, other.height))
432 }
433
434 #[inline]
436 pub fn max(self, other: Self) -> Self {
437 size2(max(self.width, other.width), max(self.height, other.height))
438 }
439
440 #[inline]
445 pub fn clamp(self, start: Self, end: Self) -> Self
446 where
447 T: Copy,
448 {
449 self.max(start).min(end)
450 }
451
452 #[inline]
454 pub fn contains(self, other: Self) -> bool {
455 self.width >= other.width && self.height >= other.height
456 }
457
458 pub fn greater_than(self, other: Self) -> BoolVector2D {
460 BoolVector2D {
461 x: self.width > other.width,
462 y: self.height > other.height,
463 }
464 }
465
466 pub fn lower_than(self, other: Self) -> BoolVector2D {
468 BoolVector2D {
469 x: self.width < other.width,
470 y: self.height < other.height,
471 }
472 }
473
474 pub fn is_empty(self) -> bool
476 where
477 T: Zero,
478 {
479 let zero = T::zero();
480 !(self.width > zero && self.height > zero)
483 }
484}
485
486impl<T: PartialEq, U> Size2D<T, U> {
487 pub fn equal(self, other: Self) -> BoolVector2D {
489 BoolVector2D {
490 x: self.width == other.width,
491 y: self.height == other.height,
492 }
493 }
494
495 pub fn not_equal(self, other: Self) -> BoolVector2D {
497 BoolVector2D {
498 x: self.width != other.width,
499 y: self.height != other.height,
500 }
501 }
502}
503
504impl<T: Round, U> Round for Size2D<T, U> {
505 #[inline]
507 fn round(self) -> Self {
508 self.round()
509 }
510}
511
512impl<T: Ceil, U> Ceil for Size2D<T, U> {
513 #[inline]
515 fn ceil(self) -> Self {
516 self.ceil()
517 }
518}
519
520impl<T: Floor, U> Floor for Size2D<T, U> {
521 #[inline]
523 fn floor(self) -> Self {
524 self.floor()
525 }
526}
527
528impl<T: Zero, U> Zero for Size2D<T, U> {
529 #[inline]
530 fn zero() -> Self {
531 Size2D::new(Zero::zero(), Zero::zero())
532 }
533}
534
535impl<T: Neg, U> Neg for Size2D<T, U> {
536 type Output = Size2D<T::Output, U>;
537
538 #[inline]
539 fn neg(self) -> Self::Output {
540 Size2D::new(-self.width, -self.height)
541 }
542}
543
544impl<T: Add, U> Add for Size2D<T, U> {
545 type Output = Size2D<T::Output, U>;
546
547 #[inline]
548 fn add(self, other: Self) -> Self::Output {
549 Size2D::new(self.width + other.width, self.height + other.height)
550 }
551}
552
553impl<T: Copy + Add<T, Output = T>, U> Add<&Self> for Size2D<T, U> {
554 type Output = Self;
555 fn add(self, other: &Self) -> Self {
556 Size2D::new(self.width + other.width, self.height + other.height)
557 }
558}
559
560impl<T: Add<Output = T> + Zero, U> Sum for Size2D<T, U> {
561 fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
562 iter.fold(Self::zero(), Add::add)
563 }
564}
565
566impl<'a, T: 'a + Add<Output = T> + Copy + Zero, U: 'a> Sum<&'a Self> for Size2D<T, U> {
567 fn sum<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
568 iter.fold(Self::zero(), Add::add)
569 }
570}
571
572impl<T: AddAssign, U> AddAssign for Size2D<T, U> {
573 #[inline]
574 fn add_assign(&mut self, other: Self) {
575 self.width += other.width;
576 self.height += other.height;
577 }
578}
579
580impl<T: Sub, U> Sub for Size2D<T, U> {
581 type Output = Size2D<T::Output, U>;
582
583 #[inline]
584 fn sub(self, other: Self) -> Self::Output {
585 Size2D::new(self.width - other.width, self.height - other.height)
586 }
587}
588
589impl<T: SubAssign, U> SubAssign for Size2D<T, U> {
590 #[inline]
591 fn sub_assign(&mut self, other: Self) {
592 self.width -= other.width;
593 self.height -= other.height;
594 }
595}
596
597impl<T: Copy + Mul, U> Mul<T> for Size2D<T, U> {
598 type Output = Size2D<T::Output, U>;
599
600 #[inline]
601 fn mul(self, scale: T) -> Self::Output {
602 Size2D::new(self.width * scale, self.height * scale)
603 }
604}
605
606impl<T: Copy + MulAssign, U> MulAssign<T> for Size2D<T, U> {
607 #[inline]
608 fn mul_assign(&mut self, other: T) {
609 self.width *= other;
610 self.height *= other;
611 }
612}
613
614impl<T: Copy + Mul, U1, U2> Mul<Scale<T, U1, U2>> for Size2D<T, U1> {
615 type Output = Size2D<T::Output, U2>;
616
617 #[inline]
618 fn mul(self, scale: Scale<T, U1, U2>) -> Self::Output {
619 Size2D::new(self.width * scale.0, self.height * scale.0)
620 }
621}
622
623impl<T: Copy + MulAssign, U> MulAssign<Scale<T, U, U>> for Size2D<T, U> {
624 #[inline]
625 fn mul_assign(&mut self, other: Scale<T, U, U>) {
626 *self *= other.0;
627 }
628}
629
630impl<T: Copy + Div, U> Div<T> for Size2D<T, U> {
631 type Output = Size2D<T::Output, U>;
632
633 #[inline]
634 fn div(self, scale: T) -> Self::Output {
635 Size2D::new(self.width / scale, self.height / scale)
636 }
637}
638
639impl<T: Copy + DivAssign, U> DivAssign<T> for Size2D<T, U> {
640 #[inline]
641 fn div_assign(&mut self, other: T) {
642 self.width /= other;
643 self.height /= other;
644 }
645}
646
647impl<T: Copy + Div, U1, U2> Div<Scale<T, U1, U2>> for Size2D<T, U2> {
648 type Output = Size2D<T::Output, U1>;
649
650 #[inline]
651 fn div(self, scale: Scale<T, U1, U2>) -> Self::Output {
652 Size2D::new(self.width / scale.0, self.height / scale.0)
653 }
654}
655
656impl<T: Copy + DivAssign, U> DivAssign<Scale<T, U, U>> for Size2D<T, U> {
657 #[inline]
658 fn div_assign(&mut self, other: Scale<T, U, U>) {
659 *self /= other.0;
660 }
661}
662
663#[inline]
665pub const fn size2<T, U>(w: T, h: T) -> Size2D<T, U> {
666 Size2D::new(w, h)
667}
668
669#[cfg(feature = "mint")]
670impl<T, U> From<mint::Vector2<T>> for Size2D<T, U> {
671 #[inline]
672 fn from(v: mint::Vector2<T>) -> Self {
673 Size2D {
674 width: v.x,
675 height: v.y,
676 _unit: PhantomData,
677 }
678 }
679}
680#[cfg(feature = "mint")]
681impl<T, U> From<Size2D<T, U>> for mint::Vector2<T> {
682 #[inline]
683 fn from(s: Size2D<T, U>) -> Self {
684 mint::Vector2 {
685 x: s.width,
686 y: s.height,
687 }
688 }
689}
690
691impl<T, U> From<Vector2D<T, U>> for Size2D<T, U> {
692 #[inline]
693 fn from(v: Vector2D<T, U>) -> Self {
694 size2(v.x, v.y)
695 }
696}
697
698impl<T, U> From<Size2D<T, U>> for [T; 2] {
699 #[inline]
700 fn from(s: Size2D<T, U>) -> Self {
701 [s.width, s.height]
702 }
703}
704
705impl<T, U> From<[T; 2]> for Size2D<T, U> {
706 #[inline]
707 fn from([w, h]: [T; 2]) -> Self {
708 size2(w, h)
709 }
710}
711
712impl<T, U> From<Size2D<T, U>> for (T, T) {
713 #[inline]
714 fn from(s: Size2D<T, U>) -> Self {
715 (s.width, s.height)
716 }
717}
718
719impl<T, U> From<(T, T)> for Size2D<T, U> {
720 #[inline]
721 fn from(tuple: (T, T)) -> Self {
722 size2(tuple.0, tuple.1)
723 }
724}
725
726#[cfg(test)]
727mod size2d {
728 use crate::default::Size2D;
729 #[cfg(feature = "mint")]
730 use mint;
731
732 #[test]
733 pub fn test_area() {
734 let p = Size2D::new(1.5, 2.0);
735 assert_eq!(p.area(), 3.0);
736 }
737
738 #[cfg(feature = "mint")]
739 #[test]
740 pub fn test_mint() {
741 let s1 = Size2D::new(1.0, 2.0);
742 let sm: mint::Vector2<_> = s1.into();
743 let s2 = Size2D::from(sm);
744
745 assert_eq!(s1, s2);
746 }
747
748 mod ops {
749 use crate::default::Size2D;
750 use crate::scale::Scale;
751
752 pub enum Mm {}
753 pub enum Cm {}
754
755 pub type Size2DMm<T> = crate::Size2D<T, Mm>;
756 pub type Size2DCm<T> = crate::Size2D<T, Cm>;
757
758 #[test]
759 pub fn test_neg() {
760 assert_eq!(-Size2D::new(1.0, 2.0), Size2D::new(-1.0, -2.0));
761 assert_eq!(-Size2D::new(0.0, 0.0), Size2D::new(-0.0, -0.0));
762 assert_eq!(-Size2D::new(-1.0, -2.0), Size2D::new(1.0, 2.0));
763 }
764
765 #[test]
766 pub fn test_add() {
767 let s1 = Size2D::new(1.0, 2.0);
768 let s2 = Size2D::new(3.0, 4.0);
769 assert_eq!(s1 + s2, Size2D::new(4.0, 6.0));
770 assert_eq!(s1 + &s2, Size2D::new(4.0, 6.0));
771
772 let s1 = Size2D::new(1.0, 2.0);
773 let s2 = Size2D::new(0.0, 0.0);
774 assert_eq!(s1 + s2, Size2D::new(1.0, 2.0));
775 assert_eq!(s1 + &s2, Size2D::new(1.0, 2.0));
776
777 let s1 = Size2D::new(1.0, 2.0);
778 let s2 = Size2D::new(-3.0, -4.0);
779 assert_eq!(s1 + s2, Size2D::new(-2.0, -2.0));
780 assert_eq!(s1 + &s2, Size2D::new(-2.0, -2.0));
781
782 let s1 = Size2D::new(0.0, 0.0);
783 let s2 = Size2D::new(0.0, 0.0);
784 assert_eq!(s1 + s2, Size2D::new(0.0, 0.0));
785 assert_eq!(s1 + &s2, Size2D::new(0.0, 0.0));
786 }
787
788 #[test]
789 pub fn test_add_assign() {
790 let mut s = Size2D::new(1.0, 2.0);
791 s += Size2D::new(3.0, 4.0);
792 assert_eq!(s, Size2D::new(4.0, 6.0));
793
794 let mut s = Size2D::new(1.0, 2.0);
795 s += Size2D::new(0.0, 0.0);
796 assert_eq!(s, Size2D::new(1.0, 2.0));
797
798 let mut s = Size2D::new(1.0, 2.0);
799 s += Size2D::new(-3.0, -4.0);
800 assert_eq!(s, Size2D::new(-2.0, -2.0));
801
802 let mut s = Size2D::new(0.0, 0.0);
803 s += Size2D::new(0.0, 0.0);
804 assert_eq!(s, Size2D::new(0.0, 0.0));
805 }
806
807 #[test]
808 pub fn test_sum() {
809 let sizes = [
810 Size2D::new(0.0, 1.0),
811 Size2D::new(1.0, 2.0),
812 Size2D::new(2.0, 3.0),
813 ];
814 let sum = Size2D::new(3.0, 6.0);
815 assert_eq!(sizes.iter().sum::<Size2D<_>>(), sum);
816 }
817
818 #[test]
819 pub fn test_sub() {
820 let s1 = Size2D::new(1.0, 2.0);
821 let s2 = Size2D::new(3.0, 4.0);
822 assert_eq!(s1 - s2, Size2D::new(-2.0, -2.0));
823
824 let s1 = Size2D::new(1.0, 2.0);
825 let s2 = Size2D::new(0.0, 0.0);
826 assert_eq!(s1 - s2, Size2D::new(1.0, 2.0));
827
828 let s1 = Size2D::new(1.0, 2.0);
829 let s2 = Size2D::new(-3.0, -4.0);
830 assert_eq!(s1 - s2, Size2D::new(4.0, 6.0));
831
832 let s1 = Size2D::new(0.0, 0.0);
833 let s2 = Size2D::new(0.0, 0.0);
834 assert_eq!(s1 - s2, Size2D::new(0.0, 0.0));
835 }
836
837 #[test]
838 pub fn test_sub_assign() {
839 let mut s = Size2D::new(1.0, 2.0);
840 s -= Size2D::new(3.0, 4.0);
841 assert_eq!(s, Size2D::new(-2.0, -2.0));
842
843 let mut s = Size2D::new(1.0, 2.0);
844 s -= Size2D::new(0.0, 0.0);
845 assert_eq!(s, Size2D::new(1.0, 2.0));
846
847 let mut s = Size2D::new(1.0, 2.0);
848 s -= Size2D::new(-3.0, -4.0);
849 assert_eq!(s, Size2D::new(4.0, 6.0));
850
851 let mut s = Size2D::new(0.0, 0.0);
852 s -= Size2D::new(0.0, 0.0);
853 assert_eq!(s, Size2D::new(0.0, 0.0));
854 }
855
856 #[test]
857 pub fn test_mul_scalar() {
858 let s1: Size2D<f32> = Size2D::new(3.0, 5.0);
859
860 let result = s1 * 5.0;
861
862 assert_eq!(result, Size2D::new(15.0, 25.0));
863 }
864
865 #[test]
866 pub fn test_mul_assign_scalar() {
867 let mut s1 = Size2D::new(3.0, 5.0);
868
869 s1 *= 5.0;
870
871 assert_eq!(s1, Size2D::new(15.0, 25.0));
872 }
873
874 #[test]
875 pub fn test_mul_scale() {
876 let s1 = Size2DMm::new(1.0, 2.0);
877 let cm_per_mm: Scale<f32, Mm, Cm> = Scale::new(0.1);
878
879 let result = s1 * cm_per_mm;
880
881 assert_eq!(result, Size2DCm::new(0.1, 0.2));
882 }
883
884 #[test]
885 pub fn test_mul_assign_scale() {
886 let mut s1 = Size2DMm::new(1.0, 2.0);
887 let scale: Scale<f32, Mm, Mm> = Scale::new(0.1);
888
889 s1 *= scale;
890
891 assert_eq!(s1, Size2DMm::new(0.1, 0.2));
892 }
893
894 #[test]
895 pub fn test_div_scalar() {
896 let s1: Size2D<f32> = Size2D::new(15.0, 25.0);
897
898 let result = s1 / 5.0;
899
900 assert_eq!(result, Size2D::new(3.0, 5.0));
901 }
902
903 #[test]
904 pub fn test_div_assign_scalar() {
905 let mut s1: Size2D<f32> = Size2D::new(15.0, 25.0);
906
907 s1 /= 5.0;
908
909 assert_eq!(s1, Size2D::new(3.0, 5.0));
910 }
911
912 #[test]
913 pub fn test_div_scale() {
914 let s1 = Size2DCm::new(0.1, 0.2);
915 let cm_per_mm: Scale<f32, Mm, Cm> = Scale::new(0.1);
916
917 let result = s1 / cm_per_mm;
918
919 assert_eq!(result, Size2DMm::new(1.0, 2.0));
920 }
921
922 #[test]
923 pub fn test_div_assign_scale() {
924 let mut s1 = Size2DMm::new(0.1, 0.2);
925 let scale: Scale<f32, Mm, Mm> = Scale::new(0.1);
926
927 s1 /= scale;
928
929 assert_eq!(s1, Size2DMm::new(1.0, 2.0));
930 }
931
932 #[test]
933 pub fn test_nan_empty() {
934 use std::f32::NAN;
935 assert!(Size2D::new(NAN, 2.0).is_empty());
936 assert!(Size2D::new(0.0, NAN).is_empty());
937 assert!(Size2D::new(NAN, -2.0).is_empty());
938 }
939 }
940}
941
942#[repr(C)]
944pub struct Size3D<T, U> {
945 pub width: T,
947 pub height: T,
949 pub depth: T,
951 #[doc(hidden)]
952 pub _unit: PhantomData<U>,
953}
954
955impl<T: Copy, U> Copy for Size3D<T, U> {}
956
957impl<T: Clone, U> Clone for Size3D<T, U> {
958 fn clone(&self) -> Self {
959 Size3D {
960 width: self.width.clone(),
961 height: self.height.clone(),
962 depth: self.depth.clone(),
963 _unit: PhantomData,
964 }
965 }
966}
967
968#[cfg(feature = "serde")]
969impl<'de, T, U> serde::Deserialize<'de> for Size3D<T, U>
970where
971 T: serde::Deserialize<'de>,
972{
973 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
974 where
975 D: serde::Deserializer<'de>,
976 {
977 let (width, height, depth) = serde::Deserialize::deserialize(deserializer)?;
978 Ok(Size3D {
979 width,
980 height,
981 depth,
982 _unit: PhantomData,
983 })
984 }
985}
986
987#[cfg(feature = "serde")]
988impl<T, U> serde::Serialize for Size3D<T, U>
989where
990 T: serde::Serialize,
991{
992 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
993 where
994 S: serde::Serializer,
995 {
996 (&self.width, &self.height, &self.depth).serialize(serializer)
997 }
998}
999
1000#[cfg(feature = "arbitrary")]
1001impl<'a, T, U> arbitrary::Arbitrary<'a> for Size3D<T, U>
1002where
1003 T: arbitrary::Arbitrary<'a>,
1004{
1005 fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
1006 let (width, height, depth) = arbitrary::Arbitrary::arbitrary(u)?;
1007 Ok(Size3D {
1008 width,
1009 height,
1010 depth,
1011 _unit: PhantomData,
1012 })
1013 }
1014}
1015
1016#[cfg(feature = "bytemuck")]
1017unsafe impl<T: Zeroable, U> Zeroable for Size3D<T, U> {}
1018
1019#[cfg(feature = "bytemuck")]
1020unsafe impl<T: Pod, U: 'static> Pod for Size3D<T, U> {}
1021
1022impl<T, U> Eq for Size3D<T, U> where T: Eq {}
1023
1024impl<T, U> PartialEq for Size3D<T, U>
1025where
1026 T: PartialEq,
1027{
1028 fn eq(&self, other: &Self) -> bool {
1029 self.width == other.width && self.height == other.height && self.depth == other.depth
1030 }
1031}
1032
1033impl<T, U> Hash for Size3D<T, U>
1034where
1035 T: Hash,
1036{
1037 fn hash<H: core::hash::Hasher>(&self, h: &mut H) {
1038 self.width.hash(h);
1039 self.height.hash(h);
1040 self.depth.hash(h);
1041 }
1042}
1043
1044impl<T: fmt::Debug, U> fmt::Debug for Size3D<T, U> {
1045 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1046 fmt::Debug::fmt(&self.width, f)?;
1047 write!(f, "x")?;
1048 fmt::Debug::fmt(&self.height, f)?;
1049 write!(f, "x")?;
1050 fmt::Debug::fmt(&self.depth, f)
1051 }
1052}
1053
1054impl<T: Default, U> Default for Size3D<T, U> {
1055 fn default() -> Self {
1056 Size3D::new(Default::default(), Default::default(), Default::default())
1057 }
1058}
1059
1060impl<T, U> Size3D<T, U> {
1061 pub fn zero() -> Self
1065 where
1066 T: Zero,
1067 {
1068 Size3D::new(Zero::zero(), Zero::zero(), Zero::zero())
1069 }
1070
1071 #[inline]
1073 pub const fn new(width: T, height: T, depth: T) -> Self {
1074 Size3D {
1075 width,
1076 height,
1077 depth,
1078 _unit: PhantomData,
1079 }
1080 }
1081 #[inline]
1083 pub fn from_lengths(width: Length<T, U>, height: Length<T, U>, depth: Length<T, U>) -> Self {
1084 Size3D::new(width.0, height.0, depth.0)
1085 }
1086
1087 #[inline]
1089 pub fn splat(v: T) -> Self
1090 where
1091 T: Clone,
1092 {
1093 Size3D {
1094 width: v.clone(),
1095 height: v.clone(),
1096 depth: v,
1097 _unit: PhantomData,
1098 }
1099 }
1100
1101 #[inline]
1103 pub fn from_untyped(p: Size3D<T, UnknownUnit>) -> Self {
1104 Size3D::new(p.width, p.height, p.depth)
1105 }
1106}
1107
1108impl<T: Copy, U> Size3D<T, U> {
1109 #[inline]
1111 pub fn to_array(self) -> [T; 3] {
1112 [self.width, self.height, self.depth]
1113 }
1114
1115 #[inline]
1117 pub fn to_tuple(self) -> (T, T, T) {
1118 (self.width, self.height, self.depth)
1119 }
1120
1121 #[inline]
1123 pub fn to_vector(self) -> Vector3D<T, U> {
1124 vec3(self.width, self.height, self.depth)
1125 }
1126
1127 #[inline]
1129 pub fn to_untyped(self) -> Size3D<T, UnknownUnit> {
1130 self.cast_unit()
1131 }
1132
1133 #[inline]
1135 pub fn cast_unit<V>(self) -> Size3D<T, V> {
1136 Size3D::new(self.width, self.height, self.depth)
1137 }
1138
1139 #[inline]
1150 #[must_use]
1151 pub fn round(self) -> Self
1152 where
1153 T: Round,
1154 {
1155 Size3D::new(self.width.round(), self.height.round(), self.depth.round())
1156 }
1157
1158 #[inline]
1169 #[must_use]
1170 pub fn ceil(self) -> Self
1171 where
1172 T: Ceil,
1173 {
1174 Size3D::new(self.width.ceil(), self.height.ceil(), self.depth.ceil())
1175 }
1176
1177 #[inline]
1188 #[must_use]
1189 pub fn floor(self) -> Self
1190 where
1191 T: Floor,
1192 {
1193 Size3D::new(self.width.floor(), self.height.floor(), self.depth.floor())
1194 }
1195
1196 pub fn volume(self) -> T
1198 where
1199 T: Mul<Output = T>,
1200 {
1201 self.width * self.height * self.depth
1202 }
1203
1204 #[inline]
1222 pub fn lerp(self, other: Self, t: T) -> Self
1223 where
1224 T: One + Sub<Output = T> + Mul<Output = T> + Add<Output = T>,
1225 {
1226 let one_t = T::one() - t;
1227 self * one_t + other * t
1228 }
1229}
1230
1231impl<T: NumCast + Copy, U> Size3D<T, U> {
1232 #[inline]
1238 pub fn cast<NewT: NumCast>(self) -> Size3D<NewT, U> {
1239 self.try_cast().unwrap()
1240 }
1241
1242 pub fn try_cast<NewT: NumCast>(self) -> Option<Size3D<NewT, U>> {
1248 match (
1249 NumCast::from(self.width),
1250 NumCast::from(self.height),
1251 NumCast::from(self.depth),
1252 ) {
1253 (Some(w), Some(h), Some(d)) => Some(Size3D::new(w, h, d)),
1254 _ => None,
1255 }
1256 }
1257
1258 #[inline]
1262 pub fn to_f32(self) -> Size3D<f32, U> {
1263 self.cast()
1264 }
1265
1266 #[inline]
1268 pub fn to_f64(self) -> Size3D<f64, U> {
1269 self.cast()
1270 }
1271
1272 #[inline]
1278 pub fn to_usize(self) -> Size3D<usize, U> {
1279 self.cast()
1280 }
1281
1282 #[inline]
1288 pub fn to_u32(self) -> Size3D<u32, U> {
1289 self.cast()
1290 }
1291
1292 #[inline]
1298 pub fn to_i32(self) -> Size3D<i32, U> {
1299 self.cast()
1300 }
1301
1302 #[inline]
1308 pub fn to_i64(self) -> Size3D<i64, U> {
1309 self.cast()
1310 }
1311}
1312
1313impl<T: Float, U> Size3D<T, U> {
1314 #[inline]
1316 pub fn is_finite(self) -> bool {
1317 self.width.is_finite() && self.height.is_finite() && self.depth.is_finite()
1318 }
1319}
1320
1321impl<T: Signed, U> Size3D<T, U> {
1322 pub fn abs(self) -> Self {
1328 size3(self.width.abs(), self.height.abs(), self.depth.abs())
1329 }
1330
1331 pub fn is_positive(self) -> bool {
1333 self.width.is_positive() && self.height.is_positive() && self.depth.is_positive()
1334 }
1335}
1336
1337impl<T: PartialOrd, U> Size3D<T, U> {
1338 #[inline]
1340 pub fn min(self, other: Self) -> Self {
1341 size3(
1342 min(self.width, other.width),
1343 min(self.height, other.height),
1344 min(self.depth, other.depth),
1345 )
1346 }
1347
1348 #[inline]
1350 pub fn max(self, other: Self) -> Self {
1351 size3(
1352 max(self.width, other.width),
1353 max(self.height, other.height),
1354 max(self.depth, other.depth),
1355 )
1356 }
1357
1358 #[inline]
1363 pub fn clamp(self, start: Self, end: Self) -> Self
1364 where
1365 T: Copy,
1366 {
1367 self.max(start).min(end)
1368 }
1369
1370 #[inline]
1372 pub fn contains(self, other: Self) -> bool {
1373 self.width >= other.width && self.height >= other.height && self.depth >= other.depth
1374 }
1375
1376 pub fn greater_than(self, other: Self) -> BoolVector3D {
1378 BoolVector3D {
1379 x: self.width > other.width,
1380 y: self.height > other.height,
1381 z: self.depth > other.depth,
1382 }
1383 }
1384
1385 pub fn lower_than(self, other: Self) -> BoolVector3D {
1387 BoolVector3D {
1388 x: self.width < other.width,
1389 y: self.height < other.height,
1390 z: self.depth < other.depth,
1391 }
1392 }
1393
1394 pub fn is_empty(self) -> bool
1396 where
1397 T: Zero,
1398 {
1399 let zero = T::zero();
1400 !(self.width > zero && self.height > zero && self.depth > zero)
1401 }
1402}
1403
1404impl<T: PartialEq, U> Size3D<T, U> {
1405 pub fn equal(self, other: Self) -> BoolVector3D {
1407 BoolVector3D {
1408 x: self.width == other.width,
1409 y: self.height == other.height,
1410 z: self.depth == other.depth,
1411 }
1412 }
1413
1414 pub fn not_equal(self, other: Self) -> BoolVector3D {
1416 BoolVector3D {
1417 x: self.width != other.width,
1418 y: self.height != other.height,
1419 z: self.depth != other.depth,
1420 }
1421 }
1422}
1423
1424impl<T: Round, U> Round for Size3D<T, U> {
1425 #[inline]
1427 fn round(self) -> Self {
1428 self.round()
1429 }
1430}
1431
1432impl<T: Ceil, U> Ceil for Size3D<T, U> {
1433 #[inline]
1435 fn ceil(self) -> Self {
1436 self.ceil()
1437 }
1438}
1439
1440impl<T: Floor, U> Floor for Size3D<T, U> {
1441 #[inline]
1443 fn floor(self) -> Self {
1444 self.floor()
1445 }
1446}
1447
1448impl<T: Zero, U> Zero for Size3D<T, U> {
1449 #[inline]
1450 fn zero() -> Self {
1451 Size3D::new(Zero::zero(), Zero::zero(), Zero::zero())
1452 }
1453}
1454
1455impl<T: Neg, U> Neg for Size3D<T, U> {
1456 type Output = Size3D<T::Output, U>;
1457
1458 #[inline]
1459 fn neg(self) -> Self::Output {
1460 Size3D::new(-self.width, -self.height, -self.depth)
1461 }
1462}
1463
1464impl<T: Add, U> Add for Size3D<T, U> {
1465 type Output = Size3D<T::Output, U>;
1466
1467 #[inline]
1468 fn add(self, other: Self) -> Self::Output {
1469 Size3D::new(
1470 self.width + other.width,
1471 self.height + other.height,
1472 self.depth + other.depth,
1473 )
1474 }
1475}
1476
1477impl<T: Copy + Add<T, Output = T>, U> Add<&Self> for Size3D<T, U> {
1478 type Output = Self;
1479 fn add(self, other: &Self) -> Self {
1480 Size3D::new(
1481 self.width + other.width,
1482 self.height + other.height,
1483 self.depth + other.depth,
1484 )
1485 }
1486}
1487
1488impl<T: Add<Output = T> + Zero, U> Sum for Size3D<T, U> {
1489 fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
1490 iter.fold(Self::zero(), Add::add)
1491 }
1492}
1493
1494impl<'a, T: 'a + Add<Output = T> + Copy + Zero, U: 'a> Sum<&'a Self> for Size3D<T, U> {
1495 fn sum<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
1496 iter.fold(Self::zero(), Add::add)
1497 }
1498}
1499
1500impl<T: AddAssign, U> AddAssign for Size3D<T, U> {
1501 #[inline]
1502 fn add_assign(&mut self, other: Self) {
1503 self.width += other.width;
1504 self.height += other.height;
1505 self.depth += other.depth;
1506 }
1507}
1508
1509impl<T: Sub, U> Sub for Size3D<T, U> {
1510 type Output = Size3D<T::Output, U>;
1511
1512 #[inline]
1513 fn sub(self, other: Self) -> Self::Output {
1514 Size3D::new(
1515 self.width - other.width,
1516 self.height - other.height,
1517 self.depth - other.depth,
1518 )
1519 }
1520}
1521
1522impl<T: SubAssign, U> SubAssign for Size3D<T, U> {
1523 #[inline]
1524 fn sub_assign(&mut self, other: Self) {
1525 self.width -= other.width;
1526 self.height -= other.height;
1527 self.depth -= other.depth;
1528 }
1529}
1530
1531impl<T: Copy + Mul, U> Mul<T> for Size3D<T, U> {
1532 type Output = Size3D<T::Output, U>;
1533
1534 #[inline]
1535 #[rustfmt::skip]
1536 fn mul(self, scale: T) -> Self::Output {
1537 Size3D::new(
1538 self.width * scale,
1539 self.height * scale,
1540 self.depth * scale,
1541 )
1542 }
1543}
1544
1545impl<T: Copy + MulAssign, U> MulAssign<T> for Size3D<T, U> {
1546 #[inline]
1547 fn mul_assign(&mut self, other: T) {
1548 self.width *= other;
1549 self.height *= other;
1550 self.depth *= other;
1551 }
1552}
1553
1554impl<T: Copy + Mul, U1, U2> Mul<Scale<T, U1, U2>> for Size3D<T, U1> {
1555 type Output = Size3D<T::Output, U2>;
1556
1557 #[inline]
1558 fn mul(self, scale: Scale<T, U1, U2>) -> Self::Output {
1559 Size3D::new(
1560 self.width * scale.0,
1561 self.height * scale.0,
1562 self.depth * scale.0,
1563 )
1564 }
1565}
1566
1567impl<T: Copy + MulAssign, U> MulAssign<Scale<T, U, U>> for Size3D<T, U> {
1568 #[inline]
1569 fn mul_assign(&mut self, other: Scale<T, U, U>) {
1570 *self *= other.0;
1571 }
1572}
1573
1574impl<T: Copy + Div, U> Div<T> for Size3D<T, U> {
1575 type Output = Size3D<T::Output, U>;
1576
1577 #[inline]
1578 #[rustfmt::skip]
1579 fn div(self, scale: T) -> Self::Output {
1580 Size3D::new(
1581 self.width / scale,
1582 self.height / scale,
1583 self.depth / scale,
1584 )
1585 }
1586}
1587
1588impl<T: Copy + DivAssign, U> DivAssign<T> for Size3D<T, U> {
1589 #[inline]
1590 fn div_assign(&mut self, other: T) {
1591 self.width /= other;
1592 self.height /= other;
1593 self.depth /= other;
1594 }
1595}
1596
1597impl<T: Copy + Div, U1, U2> Div<Scale<T, U1, U2>> for Size3D<T, U2> {
1598 type Output = Size3D<T::Output, U1>;
1599
1600 #[inline]
1601 fn div(self, scale: Scale<T, U1, U2>) -> Self::Output {
1602 Size3D::new(
1603 self.width / scale.0,
1604 self.height / scale.0,
1605 self.depth / scale.0,
1606 )
1607 }
1608}
1609
1610impl<T: Copy + DivAssign, U> DivAssign<Scale<T, U, U>> for Size3D<T, U> {
1611 #[inline]
1612 fn div_assign(&mut self, other: Scale<T, U, U>) {
1613 *self /= other.0;
1614 }
1615}
1616
1617#[cfg(feature = "mint")]
1618impl<T, U> From<mint::Vector3<T>> for Size3D<T, U> {
1619 #[inline]
1620 fn from(v: mint::Vector3<T>) -> Self {
1621 size3(v.x, v.y, v.z)
1622 }
1623}
1624#[cfg(feature = "mint")]
1625impl<T, U> From<Size3D<T, U>> for mint::Vector3<T> {
1626 #[inline]
1627 fn from(s: Size3D<T, U>) -> Self {
1628 mint::Vector3 {
1629 x: s.width,
1630 y: s.height,
1631 z: s.depth,
1632 }
1633 }
1634}
1635
1636impl<T, U> From<Vector3D<T, U>> for Size3D<T, U> {
1637 #[inline]
1638 fn from(v: Vector3D<T, U>) -> Self {
1639 size3(v.x, v.y, v.z)
1640 }
1641}
1642
1643impl<T, U> From<Size3D<T, U>> for [T; 3] {
1644 #[inline]
1645 fn from(s: Size3D<T, U>) -> Self {
1646 [s.width, s.height, s.depth]
1647 }
1648}
1649
1650impl<T, U> From<[T; 3]> for Size3D<T, U> {
1651 #[inline]
1652 fn from([w, h, d]: [T; 3]) -> Self {
1653 size3(w, h, d)
1654 }
1655}
1656
1657impl<T, U> From<Size3D<T, U>> for (T, T, T) {
1658 #[inline]
1659 fn from(s: Size3D<T, U>) -> Self {
1660 (s.width, s.height, s.depth)
1661 }
1662}
1663
1664impl<T, U> From<(T, T, T)> for Size3D<T, U> {
1665 #[inline]
1666 fn from(tuple: (T, T, T)) -> Self {
1667 size3(tuple.0, tuple.1, tuple.2)
1668 }
1669}
1670
1671#[inline]
1673pub const fn size3<T, U>(w: T, h: T, d: T) -> Size3D<T, U> {
1674 Size3D::new(w, h, d)
1675}
1676
1677#[cfg(test)]
1678mod size3d {
1679 mod ops {
1680 use crate::default::{Size2D, Size3D};
1681 use crate::scale::Scale;
1682
1683 pub enum Mm {}
1684 pub enum Cm {}
1685
1686 pub type Size3DMm<T> = crate::Size3D<T, Mm>;
1687 pub type Size3DCm<T> = crate::Size3D<T, Cm>;
1688
1689 #[test]
1690 pub fn test_neg() {
1691 assert_eq!(-Size3D::new(1.0, 2.0, 3.0), Size3D::new(-1.0, -2.0, -3.0));
1692 assert_eq!(-Size3D::new(0.0, 0.0, 0.0), Size3D::new(-0.0, -0.0, -0.0));
1693 assert_eq!(-Size3D::new(-1.0, -2.0, -3.0), Size3D::new(1.0, 2.0, 3.0));
1694 }
1695
1696 #[test]
1697 pub fn test_add() {
1698 let s1 = Size3D::new(1.0, 2.0, 3.0);
1699 let s2 = Size3D::new(4.0, 5.0, 6.0);
1700 assert_eq!(s1 + s2, Size3D::new(5.0, 7.0, 9.0));
1701 assert_eq!(s1 + &s2, Size3D::new(5.0, 7.0, 9.0));
1702
1703 let s1 = Size3D::new(1.0, 2.0, 3.0);
1704 let s2 = Size3D::new(0.0, 0.0, 0.0);
1705 assert_eq!(s1 + s2, Size3D::new(1.0, 2.0, 3.0));
1706 assert_eq!(s1 + &s2, Size3D::new(1.0, 2.0, 3.0));
1707
1708 let s1 = Size3D::new(1.0, 2.0, 3.0);
1709 let s2 = Size3D::new(-4.0, -5.0, -6.0);
1710 assert_eq!(s1 + s2, Size3D::new(-3.0, -3.0, -3.0));
1711 assert_eq!(s1 + &s2, Size3D::new(-3.0, -3.0, -3.0));
1712
1713 let s1 = Size3D::new(0.0, 0.0, 0.0);
1714 let s2 = Size3D::new(0.0, 0.0, 0.0);
1715 assert_eq!(s1 + s2, Size3D::new(0.0, 0.0, 0.0));
1716 assert_eq!(s1 + &s2, Size3D::new(0.0, 0.0, 0.0));
1717 }
1718
1719 #[test]
1720 pub fn test_sum() {
1721 let sizes = [
1722 Size3D::new(0.0, 1.0, 2.0),
1723 Size3D::new(1.0, 2.0, 3.0),
1724 Size3D::new(2.0, 3.0, 4.0),
1725 ];
1726 let sum = Size3D::new(3.0, 6.0, 9.0);
1727 assert_eq!(sizes.iter().sum::<Size3D<_>>(), sum);
1728 }
1729
1730 #[test]
1731 pub fn test_add_assign() {
1732 let mut s = Size3D::new(1.0, 2.0, 3.0);
1733 s += Size3D::new(4.0, 5.0, 6.0);
1734 assert_eq!(s, Size3D::new(5.0, 7.0, 9.0));
1735
1736 let mut s = Size3D::new(1.0, 2.0, 3.0);
1737 s += Size3D::new(0.0, 0.0, 0.0);
1738 assert_eq!(s, Size3D::new(1.0, 2.0, 3.0));
1739
1740 let mut s = Size3D::new(1.0, 2.0, 3.0);
1741 s += Size3D::new(-4.0, -5.0, -6.0);
1742 assert_eq!(s, Size3D::new(-3.0, -3.0, -3.0));
1743
1744 let mut s = Size3D::new(0.0, 0.0, 0.0);
1745 s += Size3D::new(0.0, 0.0, 0.0);
1746 assert_eq!(s, Size3D::new(0.0, 0.0, 0.0));
1747 }
1748
1749 #[test]
1750 pub fn test_sub() {
1751 let s1 = Size3D::new(1.0, 2.0, 3.0);
1752 let s2 = Size3D::new(4.0, 5.0, 6.0);
1753 assert_eq!(s1 - s2, Size3D::new(-3.0, -3.0, -3.0));
1754
1755 let s1 = Size3D::new(1.0, 2.0, 3.0);
1756 let s2 = Size3D::new(0.0, 0.0, 0.0);
1757 assert_eq!(s1 - s2, Size3D::new(1.0, 2.0, 3.0));
1758
1759 let s1 = Size3D::new(1.0, 2.0, 3.0);
1760 let s2 = Size3D::new(-4.0, -5.0, -6.0);
1761 assert_eq!(s1 - s2, Size3D::new(5.0, 7.0, 9.0));
1762
1763 let s1 = Size3D::new(0.0, 0.0, 0.0);
1764 let s2 = Size3D::new(0.0, 0.0, 0.0);
1765 assert_eq!(s1 - s2, Size3D::new(0.0, 0.0, 0.0));
1766 }
1767
1768 #[test]
1769 pub fn test_sub_assign() {
1770 let mut s = Size3D::new(1.0, 2.0, 3.0);
1771 s -= Size3D::new(4.0, 5.0, 6.0);
1772 assert_eq!(s, Size3D::new(-3.0, -3.0, -3.0));
1773
1774 let mut s = Size3D::new(1.0, 2.0, 3.0);
1775 s -= Size3D::new(0.0, 0.0, 0.0);
1776 assert_eq!(s, Size3D::new(1.0, 2.0, 3.0));
1777
1778 let mut s = Size3D::new(1.0, 2.0, 3.0);
1779 s -= Size3D::new(-4.0, -5.0, -6.0);
1780 assert_eq!(s, Size3D::new(5.0, 7.0, 9.0));
1781
1782 let mut s = Size3D::new(0.0, 0.0, 0.0);
1783 s -= Size3D::new(0.0, 0.0, 0.0);
1784 assert_eq!(s, Size3D::new(0.0, 0.0, 0.0));
1785 }
1786
1787 #[test]
1788 pub fn test_mul_scalar() {
1789 let s1: Size3D<f32> = Size3D::new(3.0, 5.0, 7.0);
1790
1791 let result = s1 * 5.0;
1792
1793 assert_eq!(result, Size3D::new(15.0, 25.0, 35.0));
1794 }
1795
1796 #[test]
1797 pub fn test_mul_assign_scalar() {
1798 let mut s1: Size3D<f32> = Size3D::new(3.0, 5.0, 7.0);
1799
1800 s1 *= 5.0;
1801
1802 assert_eq!(s1, Size3D::new(15.0, 25.0, 35.0));
1803 }
1804
1805 #[test]
1806 pub fn test_mul_scale() {
1807 let s1 = Size3DMm::new(1.0, 2.0, 3.0);
1808 let cm_per_mm: Scale<f32, Mm, Cm> = Scale::new(0.1);
1809
1810 let result = s1 * cm_per_mm;
1811
1812 assert_eq!(result, Size3DCm::new(0.1, 0.2, 0.3));
1813 }
1814
1815 #[test]
1816 pub fn test_mul_assign_scale() {
1817 let mut s1 = Size3DMm::new(1.0, 2.0, 3.0);
1818 let scale: Scale<f32, Mm, Mm> = Scale::new(0.1);
1819
1820 s1 *= scale;
1821
1822 assert_eq!(s1, Size3DMm::new(0.1, 0.2, 0.3));
1823 }
1824
1825 #[test]
1826 pub fn test_div_scalar() {
1827 let s1: Size3D<f32> = Size3D::new(15.0, 25.0, 35.0);
1828
1829 let result = s1 / 5.0;
1830
1831 assert_eq!(result, Size3D::new(3.0, 5.0, 7.0));
1832 }
1833
1834 #[test]
1835 pub fn test_div_assign_scalar() {
1836 let mut s1: Size3D<f32> = Size3D::new(15.0, 25.0, 35.0);
1837
1838 s1 /= 5.0;
1839
1840 assert_eq!(s1, Size3D::new(3.0, 5.0, 7.0));
1841 }
1842
1843 #[test]
1844 pub fn test_div_scale() {
1845 let s1 = Size3DCm::new(0.1, 0.2, 0.3);
1846 let cm_per_mm: Scale<f32, Mm, Cm> = Scale::new(0.1);
1847
1848 let result = s1 / cm_per_mm;
1849
1850 assert_eq!(result, Size3DMm::new(1.0, 2.0, 3.0));
1851 }
1852
1853 #[test]
1854 pub fn test_div_assign_scale() {
1855 let mut s1 = Size3DMm::new(0.1, 0.2, 0.3);
1856 let scale: Scale<f32, Mm, Mm> = Scale::new(0.1);
1857
1858 s1 /= scale;
1859
1860 assert_eq!(s1, Size3DMm::new(1.0, 2.0, 3.0));
1861 }
1862
1863 #[test]
1864 fn test_nonempty() {
1865 assert!(!Size2D::new(1.0, 1.0).is_empty());
1866 assert!(!Size3D::new(1.0, 1.0, 1.0).is_empty());
1867 }
1868
1869 #[test]
1870 pub fn test_nan_empty() {
1871 use std::f32::NAN;
1872 assert!(Size3D::new(NAN, 2.0, 3.0).is_empty());
1873 assert!(Size3D::new(0.0, NAN, 0.0).is_empty());
1874 assert!(Size3D::new(1.0, 2.0, NAN).is_empty());
1875 }
1876 }
1877}