summary refs log tree commit diff stats
path: root/rust/hw/char/pl011/src
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2024-12-04 08:58:46 +0100
committerPaolo Bonzini <pbonzini@redhat.com>2025-01-10 23:34:44 +0100
commit809c703a60240125eec16ec134f60793134b4f61 (patch)
tree2d7cbaf0524a078cc85ceb52cf7d3ff377c51ea6 /rust/hw/char/pl011/src
parenta3b620fff73ec762f2a77a077eb8389dddab4833 (diff)
downloadfocaccia-qemu-809c703a60240125eec16ec134f60793134b4f61.tar.gz
focaccia-qemu-809c703a60240125eec16ec134f60793134b4f61.zip
rust: qemu-api-macros: add automatic TryFrom/TryInto derivation
This is going to be fairly common. Using a custom procedural macro
provides better error messages and automatically finds the right
type.

Note that this is different from the same-named macro in the
derive_more crate.  That one provides conversion from e.g. tuples
to enums with tuple variants, not from integers to enums.

Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'rust/hw/char/pl011/src')
-rw-r--r--rust/hw/char/pl011/src/lib.rs28
1 files changed, 1 insertions, 27 deletions
diff --git a/rust/hw/char/pl011/src/lib.rs b/rust/hw/char/pl011/src/lib.rs
index 69064d6929..0a89d393e0 100644
--- a/rust/hw/char/pl011/src/lib.rs
+++ b/rust/hw/char/pl011/src/lib.rs
@@ -45,7 +45,7 @@ pub const TYPE_PL011_LUMINARY: &::std::ffi::CStr = c_str!("pl011_luminary");
 #[doc(alias = "offset")]
 #[allow(non_camel_case_types)]
 #[repr(u64)]
-#[derive(Debug)]
+#[derive(Debug, qemu_api_macros::TryInto)]
 pub enum RegisterOffset {
     /// Data Register
     ///
@@ -102,32 +102,6 @@ pub enum RegisterOffset {
     //Reserved = 0x04C,
 }
 
-impl core::convert::TryFrom<u64> for RegisterOffset {
-    type Error = u64;
-
-    fn try_from(value: u64) -> Result<Self, Self::Error> {
-        macro_rules! case {
-            ($($discriminant:ident),*$(,)*) => {
-                /* check that matching on all macro arguments compiles, which means we are not
-                 * missing any enum value; if the type definition ever changes this will stop
-                 * compiling.
-                 */
-                const fn _assert_exhaustive(val: RegisterOffset) {
-                    match val {
-                        $(RegisterOffset::$discriminant => (),)*
-                    }
-                }
-
-                match value {
-                    $(x if x == Self::$discriminant as u64 => Ok(Self::$discriminant),)*
-                     _ => Err(value),
-                }
-            }
-        }
-        case! { DR, RSR, FR, FBRD, ILPR, IBRD, LCR_H, CR, FLS, IMSC, RIS, MIS, ICR, DMACR }
-    }
-}
-
 pub mod registers {
     //! Device registers exposed as typed structs which are backed by arbitrary
     //! integer bitmaps. [`Data`], [`Control`], [`LineControl`], etc.