From 8445f41e8711cff55107d95e44381ef8915e31cb Mon Sep 17 00:00:00 2001 From: Martin Robinson Date: Mon, 21 Sep 2026 07:35:04 +0200 Subject: [PATCH] Generate enum conversion functions with a macro Normally I'm not a fan of macros, but in this case this will save hundreds of lines of code as there are going to be ~5 macro types each with their own conversion routines. Signed-off-by: Martin Robinson --- src/adapter.rs | 95 +++++++------------------------------------------- src/macros.rs | 24 +++++++++++++ 2 files changed, 36 insertions(+), 83 deletions(-) diff --git a/src/adapter.rs b/src/adapter.rs index 354c53a4..45aaf281 100644 --- a/src/adapter.rs +++ b/src/adapter.rs @@ -14,7 +14,7 @@ use crate::free_unix::adapter::FreeUnixAdapter; use crate::hardware_buffer::adapter::HardwareBufferAdapter; #[cfg(all(windows_platform, not(feature = "sm-no-wgl")))] use crate::wgl::adapter::WglAdapter; -use crate::Error; +use crate::{macros::enum_conversion, Error}; /// A power usage preference for selecting an adapter. #[derive(Copy, Clone, Debug, Default)] @@ -68,89 +68,18 @@ pub enum Adapter { Wgl(WglAdapter), } -impl Adapter { - /// Try to convert this generic [`Adapter`] into an [`AngleAdapter`]. - #[cfg(all(windows_platform, feature = "sm-angle"))] - pub fn angle(&self) -> Result<&AngleAdapter, Error> { - #[allow(unreachable_patterns)] - match self { - Adapter::Angle(ref adapter) => Ok(adapter), - _ => Err(Error::IncompatibleAdapter), - } - } - - /// Try to convert this generic [`Adapter`] into an [`IoSurfaceAdapter`]. - #[cfg(macos_platform)] - pub fn apple(&self) -> Result<&AppleAdapter, Error> { - #[allow(unreachable_patterns)] - match self { - Adapter::Apple(ref adapter) => Ok(adapter), - _ => Err(Error::IncompatibleAdapter), - } - } - - /// Try to convert this generic [`Adapter`] into a [`FreeUnixAdapter`]. - #[cfg(free_unix)] - pub fn free_unix(&self) -> Result<&FreeUnixAdapter, Error> { - #[allow(unreachable_patterns)] - match self { - Adapter::FreeUnix(ref adapter) => Ok(adapter), - _ => Err(Error::IncompatibleAdapter), - } - } - - /// Try to convert this generic [`Adapter`] into a [`HardwareBufferAdapter`]. - #[cfg(any(android_platform, ohos_platform))] - pub fn hardware_buffer(&self) -> Result<&HardwareBufferAdapter, Error> { - #[allow(unreachable_patterns)] - match self { - Adapter::HardwareBuffer(ref adapter) => Ok(adapter), - _ => Err(Error::IncompatibleAdapter), - } - } - - /// Try to convert this generic [`Adapter`] into a [`WglAdapter`]. - #[cfg(all(windows_platform, not(feature = "sm-no-wgl")))] - pub fn wgl(&self) -> Result<&WglAdapter, Error> { - #[allow(unreachable_patterns)] - match self { - Adapter::Wgl(ref adapter) => Ok(adapter), - _ => Err(Error::IncompatibleAdapter), - } - } -} - #[cfg(all(windows_platform, feature = "sm-angle"))] -impl From for Adapter { - fn from(adapter: AngleAdapter) -> Self { - Self::Angle(adapter) - } -} - +enum_conversion!(Adapter, Angle, AngleAdapter, angle); #[cfg(macos_platform)] -impl From for Adapter { - fn from(adapter: AppleAdapter) -> Self { - Self::Apple(adapter) - } -} - -#[cfg(any(android_platform, ohos_platform))] -impl From for Adapter { - fn from(adapter: HardwareBufferAdapter) -> Self { - Self::HardwareBuffer(adapter) - } -} - +enum_conversion!(Adapter, Apple, AppleAdapter, apple); #[cfg(free_unix)] -impl From for Adapter { - fn from(adapter: FreeUnixAdapter) -> Self { - Self::FreeUnix(adapter) - } -} - +enum_conversion!(Adapter, FreeUnix, FreeUnixAdapter, free_unix); +#[cfg(any(android_platform, ohos_platform))] +enum_conversion!( + Adapter, + HardwareBuffer, + HardwareBufferAdapter, + hardware_buffer +); #[cfg(all(windows_platform, not(feature = "sm-no-wgl")))] -impl From for Adapter { - fn from(adapter: WglAdapter) -> Self { - Self::Wgl(adapter) - } -} +enum_conversion!(Adapter, Wgl, WglAdapter, wgl); diff --git a/src/macros.rs b/src/macros.rs index 508b1ed3..7021ba73 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -296,4 +296,28 @@ macro_rules! implement_interfaces { }; } +/// A macro that takes care of producing the boilerplate for conversion to and +/// from an inner type within an enum. +macro_rules! enum_conversion { + ($enum:ty, $variant:ident, $type:ty, $name:ident) => { + impl From<$type> for $enum { + fn from(connection: $type) -> Self { + Self::$variant(connection) + } + } + + impl $enum { + #[doc = concat!("Try to convert this generic [`", stringify!($enum), "`] into a [`", stringify!($type), "`].")] + pub fn $name(&self) -> Result<&$type, Error> { + #[allow(unreachable_patterns)] + match self { + Self::$variant(ref connection) => Ok(connection), + _ => Err(Error::Failed), + } + } + } + }; +} + +pub(crate) use enum_conversion; pub(crate) use implement_interfaces;