From 0dc0d49d8dc54d0b2bac38df78c761a64b1341f2 Mon Sep 17 00:00:00 2001 From: Nico Burns Date: Thu, 12 Dec 2024 13:00:39 +1300 Subject: [PATCH 1/5] Implement ToPrimitive and NumCast traits Signed-off-by: Nico Burns --- src/app_unit.rs | 86 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/src/app_unit.rs b/src/app_unit.rs index 07473c9..621f56b 100644 --- a/src/app_unit.rs +++ b/src/app_unit.rs @@ -289,6 +289,92 @@ impl Au { } } +#[cfg(feature = "num_traits")] +impl num_traits::ToPrimitive for Au { + // Float conversions + + #[inline] + fn to_f32(&self) -> Option { + Some(self.to_f32_px()) + } + + #[inline] + fn to_f64(&self) -> Option { + Some(self.to_f64_px()) + } + + // Signed int conversions + + #[inline] + fn to_i8(&self) -> Option { + None + } + + #[inline] + fn to_i16(&self) -> Option { + None + } + + #[inline] + fn to_i32(&self) -> Option { + Some(self.to_px()) + } + + #[inline] + fn to_i64(&self) -> Option { + Some(self.to_px() as i64) + } + + #[inline] + fn to_i128(&self) -> Option { + Some(self.to_px() as i128) + } + + #[inline] + fn to_isize(&self) -> Option { + Some(self.to_px() as isize) + } + + // Unsigned int conversions + + #[inline] + fn to_u8(&self) -> Option { + None + } + + #[inline] + fn to_u16(&self) -> Option { + None + } + + #[inline] + fn to_u32(&self) -> Option { + None + } + + #[inline] + fn to_u64(&self) -> Option { + None + } + + #[inline] + fn to_u128(&self) -> Option { + None + } + + #[inline] + fn to_usize(&self) -> Option { + None + } +} + +#[cfg(feature = "num_traits")] +impl num_traits::NumCast for Au { + fn from(n: T) -> Option { + n.to_f64().map(Self::from_f64_px) + } +} + #[test] fn create() { assert_eq!(Au::zero(), Au(0)); From 7ce8644ff2f16164a002cd71fb0959afe2ea776b Mon Sep 17 00:00:00 2001 From: Nico Burns Date: Thu, 12 Dec 2024 13:35:27 +1300 Subject: [PATCH 2/5] Bump version to 0.7.7 Signed-off-by: Nico Burns --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index f39090c..53d1106 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "app_units" -version = "0.7.6" +version = "0.7.7" authors = ["The Servo Project Developers"] description = "Servo app units type (Au)" documentation = "https://docs.rs/app_units/" From aa000a25e05db9e8e7482c462d608ab06eabd99b Mon Sep 17 00:00:00 2001 From: Nico Burns Date: Thu, 12 Dec 2024 13:45:45 +1300 Subject: [PATCH 3/5] Add test for euclid casting Signed-off-by: Nico Burns --- Cargo.toml | 1 + src/app_unit.rs | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index 53d1106..8f2f887 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,6 +13,7 @@ num-traits = { version = "0.2", optional = true } serde = { version = "1.0", optional = true, features = ["derive"] } [dev-dependencies] +euclid = "0.22.11" ron = "0.8.0" [features] diff --git a/src/app_unit.rs b/src/app_unit.rs index 621f56b..a9bb754 100644 --- a/src/app_unit.rs +++ b/src/app_unit.rs @@ -539,3 +539,27 @@ fn serialize() { let serialized = ron::to_string(&Au(42)).unwrap(); assert_eq!(ron::from_str(&serialized), Ok(Au(42))); } + +#[cfg(feature = "num_traits")] +#[test] +fn euclid_cast_au_to_f32() { + use euclid::default::Size2D; + let size_au: Size2D = Size2D::new(Au::new(20), Au::new(30)); + let size_f32_manual: Size2D = + Size2D::new(Au::new(20).to_f32_px(), Au::new(30).to_f32_px()); + let size_f32_cast: Size2D = size_au.cast(); + + assert_eq!(size_f32_manual, size_f32_cast); +} + +#[cfg(feature = "num_traits")] +#[test] +fn euclid_cast_f32_to_au() { + use euclid::default::Size2D; + let size_f32: Size2D = Size2D::new(3.1456, 245.043656); + let size_au_manual: Size2D = + Size2D::new(Au::from_f32_px(3.1456), Au::from_f32_px(245.043656)); + let size_au_cast: Size2D = size_f32.cast(); + + assert_eq!(size_au_manual, size_au_cast); +} From 48912414c225071c88141e941a6e3ec2c109ba80 Mon Sep 17 00:00:00 2001 From: Nico Burns Date: Fri, 13 Dec 2024 12:56:54 +1300 Subject: [PATCH 4/5] Remove unnecessary functions from ToPrimitive impl --- src/app_unit.rs | 44 +++----------------------------------------- 1 file changed, 3 insertions(+), 41 deletions(-) diff --git a/src/app_unit.rs b/src/app_unit.rs index a9bb754..ee43d6e 100644 --- a/src/app_unit.rs +++ b/src/app_unit.rs @@ -290,9 +290,10 @@ impl Au { } #[cfg(feature = "num_traits")] +// Note: +// - Conversions to isize and i128 are done implicitly based on the i64 impl +// - Conversions to other uint types are done implicitly based on the u64 impl impl num_traits::ToPrimitive for Au { - // Float conversions - #[inline] fn to_f32(&self) -> Option { Some(self.to_f32_px()) @@ -303,8 +304,6 @@ impl num_traits::ToPrimitive for Au { Some(self.to_f64_px()) } - // Signed int conversions - #[inline] fn to_i8(&self) -> Option { None @@ -325,47 +324,10 @@ impl num_traits::ToPrimitive for Au { Some(self.to_px() as i64) } - #[inline] - fn to_i128(&self) -> Option { - Some(self.to_px() as i128) - } - - #[inline] - fn to_isize(&self) -> Option { - Some(self.to_px() as isize) - } - - // Unsigned int conversions - - #[inline] - fn to_u8(&self) -> Option { - None - } - - #[inline] - fn to_u16(&self) -> Option { - None - } - - #[inline] - fn to_u32(&self) -> Option { - None - } - #[inline] fn to_u64(&self) -> Option { None } - - #[inline] - fn to_u128(&self) -> Option { - None - } - - #[inline] - fn to_usize(&self) -> Option { - None - } } #[cfg(feature = "num_traits")] From 77b4a6c3762d5c351b550cecc3d0ff9f988a00f5 Mon Sep 17 00:00:00 2001 From: Nico Burns Date: Fri, 13 Dec 2024 12:57:50 +1300 Subject: [PATCH 5/5] Add more tests Signed-off-by: Nico Burns --- src/app_unit.rs | 44 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/src/app_unit.rs b/src/app_unit.rs index ee43d6e..1bbd919 100644 --- a/src/app_unit.rs +++ b/src/app_unit.rs @@ -502,13 +502,51 @@ fn serialize() { assert_eq!(ron::from_str(&serialized), Ok(Au(42))); } +#[cfg(feature = "num_traits")] +#[test] +fn cast_au_u64() { + let val: Au = Au::new(120); + let cast: Option = num_traits::NumCast::from(val); + assert_eq!(cast, None) +} + +#[cfg(feature = "num_traits")] +#[test] +fn cast_au_i16() { + let val: Au = Au::new(120); + let cast: Option = num_traits::NumCast::from(val); + assert_eq!(cast, None) +} + +#[cfg(feature = "num_traits")] +#[test] +fn cast_au_i64() { + let val: Au = Au::new(120); + let cast: Option = num_traits::NumCast::from(val); + assert_eq!(cast, Some(2)) +} + +#[test] +fn cast_au_f32() { + let val: Au = Au::new(120); + let cast: Option = num_traits::NumCast::from(val); + assert_eq!(cast, Some(2.0)) +} + +#[cfg(feature = "num_traits")] +#[test] +fn cast_au_f64() { + let val: Au = Au::new(120); + let cast: Option = num_traits::NumCast::from(val); + assert_eq!(cast, Some(2.0)) +} + #[cfg(feature = "num_traits")] #[test] fn euclid_cast_au_to_f32() { use euclid::default::Size2D; - let size_au: Size2D = Size2D::new(Au::new(20), Au::new(30)); - let size_f32_manual: Size2D = - Size2D::new(Au::new(20).to_f32_px(), Au::new(30).to_f32_px()); + let size_au: Size2D = Size2D::new(Au::new(20 * 60), Au::new(30 * 60)); + let size_f32_manual: Size2D = Size2D::new(20.0, 30.0); let size_f32_cast: Size2D = size_au.cast(); assert_eq!(size_f32_manual, size_f32_cast);