diff --git a/Cargo.toml b/Cargo.toml index f39090c..8f2f887 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/" @@ -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 07473c9..1bbd919 100644 --- a/src/app_unit.rs +++ b/src/app_unit.rs @@ -289,6 +289,54 @@ 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 { + #[inline] + fn to_f32(&self) -> Option { + Some(self.to_f32_px()) + } + + #[inline] + fn to_f64(&self) -> Option { + Some(self.to_f64_px()) + } + + #[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_u64(&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)); @@ -453,3 +501,65 @@ 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 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 * 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); +} + +#[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); +}