From 4fda048729ccbf6642e708d6435bfda6b64e902f Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Tue, 17 Feb 2026 15:45:53 +0100 Subject: [PATCH] Reduce duplication in `dpi` module (#2148) * Deduplicate Pixel impl for integers using a macro * Deduplicate [Logical|Physical][Size|Position] From impls using a macro Co-authored-by: Osspial --- dpi/src/lib.rs | 234 ++++++++++++------------------------------------- 1 file changed, 57 insertions(+), 177 deletions(-) diff --git a/dpi/src/lib.rs b/dpi/src/lib.rs index 12389a7b1..d1dea21f6 100644 --- a/dpi/src/lib.rs +++ b/dpi/src/lib.rs @@ -84,36 +84,18 @@ pub trait Pixel: Copy + Into { } } -impl Pixel for u8 { - fn from_f64(f: f64) -> Self { - round(f) as u8 - } -} -impl Pixel for u16 { - fn from_f64(f: f64) -> Self { - round(f) as u16 - } -} -impl Pixel for u32 { - fn from_f64(f: f64) -> Self { - round(f) as u32 - } -} -impl Pixel for i8 { - fn from_f64(f: f64) -> Self { - round(f) as i8 - } -} -impl Pixel for i16 { - fn from_f64(f: f64) -> Self { - round(f) as i16 - } -} -impl Pixel for i32 { - fn from_f64(f: f64) -> Self { - round(f) as i32 - } +macro_rules! pixel_int_impl { + ($($t:ty),*) => {$( + impl Pixel for $t { + fn from_f64(f: f64) -> Self { + round(f) as $t + } + } + )*} } + +pixel_int_impl!(u8, u16, u32, i8, i16, i32); + impl Pixel for f32 { fn from_f64(f: f64) -> Self { f as f32 @@ -378,6 +360,48 @@ impl From> for PixelUnit { } } +macro_rules! vec2_from_impls { + ($t:ident, $a:ident, $b:ident, $mint_ty:ident) => { + impl From<(X, X)> for $t

{ + fn from(($a, $b): (X, X)) -> Self { + Self::new($a.cast(), $b.cast()) + } + } + + impl From<$t

> for (X, X) { + fn from(p: $t

) -> Self { + (p.$a.cast(), p.$b.cast()) + } + } + + impl From<[X; 2]> for $t

{ + fn from([$a, $b]: [X; 2]) -> Self { + Self::new($a.cast(), $b.cast()) + } + } + + impl From<$t

> for [X; 2] { + fn from(p: $t

) -> Self { + [p.$a.cast(), p.$b.cast()] + } + } + + #[cfg(feature = "mint")] + impl From> for $t

{ + fn from(p: mint::$mint_ty

) -> Self { + Self::new(p.x, p.y) + } + } + + #[cfg(feature = "mint")] + impl From<$t

> for mint::$mint_ty

{ + fn from(p: $t

) -> Self { + Self { x: p.$a, y: p.$b } + } + } + }; +} + /// A position represented in logical pixels. /// /// The position is stored as floats, so please be careful. Casting floats to integers truncates the @@ -420,43 +444,7 @@ impl LogicalPosition

{ } } -impl From<(X, X)> for LogicalPosition

{ - fn from((x, y): (X, X)) -> LogicalPosition

{ - LogicalPosition::new(x.cast(), y.cast()) - } -} - -impl From> for (X, X) { - fn from(p: LogicalPosition

) -> (X, X) { - (p.x.cast(), p.y.cast()) - } -} - -impl From<[X; 2]> for LogicalPosition

{ - fn from([x, y]: [X; 2]) -> LogicalPosition

{ - LogicalPosition::new(x.cast(), y.cast()) - } -} - -impl From> for [X; 2] { - fn from(p: LogicalPosition

) -> [X; 2] { - [p.x.cast(), p.y.cast()] - } -} - -#[cfg(feature = "mint")] -impl From> for LogicalPosition

{ - fn from(p: mint::Point2

) -> Self { - Self::new(p.x, p.y) - } -} - -#[cfg(feature = "mint")] -impl From> for mint::Point2

{ - fn from(p: LogicalPosition

) -> Self { - mint::Point2 { x: p.x, y: p.y } - } -} +vec2_from_impls!(LogicalPosition, x, y, Point2); /// A position represented in physical pixels. #[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Default, Hash)] @@ -496,43 +484,7 @@ impl PhysicalPosition

{ } } -impl From<(X, X)> for PhysicalPosition

{ - fn from((x, y): (X, X)) -> PhysicalPosition

{ - PhysicalPosition::new(x.cast(), y.cast()) - } -} - -impl From> for (X, X) { - fn from(p: PhysicalPosition

) -> (X, X) { - (p.x.cast(), p.y.cast()) - } -} - -impl From<[X; 2]> for PhysicalPosition

{ - fn from([x, y]: [X; 2]) -> PhysicalPosition

{ - PhysicalPosition::new(x.cast(), y.cast()) - } -} - -impl From> for [X; 2] { - fn from(p: PhysicalPosition

) -> [X; 2] { - [p.x.cast(), p.y.cast()] - } -} - -#[cfg(feature = "mint")] -impl From> for PhysicalPosition

{ - fn from(p: mint::Point2

) -> Self { - Self::new(p.x, p.y) - } -} - -#[cfg(feature = "mint")] -impl From> for mint::Point2

{ - fn from(p: PhysicalPosition

) -> Self { - mint::Point2 { x: p.x, y: p.y } - } -} +vec2_from_impls!(PhysicalPosition, x, y, Point2); /// A size represented in logical pixels. #[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Default, Hash)] @@ -572,43 +524,7 @@ impl LogicalSize

{ } } -impl From<(X, X)> for LogicalSize

{ - fn from((x, y): (X, X)) -> LogicalSize

{ - LogicalSize::new(x.cast(), y.cast()) - } -} - -impl From> for (X, X) { - fn from(s: LogicalSize

) -> (X, X) { - (s.width.cast(), s.height.cast()) - } -} - -impl From<[X; 2]> for LogicalSize

{ - fn from([x, y]: [X; 2]) -> LogicalSize

{ - LogicalSize::new(x.cast(), y.cast()) - } -} - -impl From> for [X; 2] { - fn from(s: LogicalSize

) -> [X; 2] { - [s.width.cast(), s.height.cast()] - } -} - -#[cfg(feature = "mint")] -impl From> for LogicalSize

{ - fn from(v: mint::Vector2

) -> Self { - Self::new(v.x, v.y) - } -} - -#[cfg(feature = "mint")] -impl From> for mint::Vector2

{ - fn from(s: LogicalSize

) -> Self { - mint::Vector2 { x: s.width, y: s.height } - } -} +vec2_from_impls!(LogicalSize, width, height, Vector2); /// A size represented in physical pixels. #[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Default, Hash)] @@ -645,43 +561,7 @@ impl PhysicalSize

{ } } -impl From<(X, X)> for PhysicalSize

{ - fn from((x, y): (X, X)) -> PhysicalSize

{ - PhysicalSize::new(x.cast(), y.cast()) - } -} - -impl From> for (X, X) { - fn from(s: PhysicalSize

) -> (X, X) { - (s.width.cast(), s.height.cast()) - } -} - -impl From<[X; 2]> for PhysicalSize

{ - fn from([x, y]: [X; 2]) -> PhysicalSize

{ - PhysicalSize::new(x.cast(), y.cast()) - } -} - -impl From> for [X; 2] { - fn from(s: PhysicalSize

) -> [X; 2] { - [s.width.cast(), s.height.cast()] - } -} - -#[cfg(feature = "mint")] -impl From> for PhysicalSize

{ - fn from(v: mint::Vector2

) -> Self { - Self::new(v.x, v.y) - } -} - -#[cfg(feature = "mint")] -impl From> for mint::Vector2

{ - fn from(s: PhysicalSize

) -> Self { - mint::Vector2 { x: s.width, y: s.height } - } -} +vec2_from_impls!(PhysicalSize, width, height, Vector2); /// A size that's either physical or logical. #[derive(Debug, Copy, Clone, PartialEq)]