Prepare for having ObjectClass, DeviceClass and SysbusDeviceClass
defined outside the hwcore and qom crates.  It then becomes
impossible to add a method to them.

Extracted from a patch by Marc-André Lureau.

Signed-off-by: Paolo Bonzini <[email protected]>
---
 rust/hw/core/src/prelude.rs |  3 +++
 rust/hw/core/src/qdev.rs    | 25 +++++++++++++++----------
 rust/hw/core/src/sysbus.rs  | 10 +++++++---
 rust/qom/src/prelude.rs     |  1 +
 rust/qom/src/qom.rs         |  8 ++++++--
 5 files changed, 32 insertions(+), 15 deletions(-)

diff --git a/rust/hw/core/src/prelude.rs b/rust/hw/core/src/prelude.rs
index c544c317b39..13f7dfc6809 100644
--- a/rust/hw/core/src/prelude.rs
+++ b/rust/hw/core/src/prelude.rs
@@ -1,6 +1,8 @@
 //! Essential types and traits intended for blanket imports.
 
 pub use crate::qdev::Clock;
+
+pub use crate::qdev::DeviceClassExt;
 pub use crate::qdev::DeviceState;
 pub use crate::qdev::DeviceImpl;
 pub use crate::qdev::DeviceMethods;
@@ -8,6 +10,7 @@
 pub use crate::qdev::ResetType;
 
 pub use crate::sysbus::SysBusDevice;
+pub use crate::sysbus::SysBusDeviceClassExt;
 pub use crate::sysbus::SysBusDeviceImpl;
 pub use crate::sysbus::SysBusDeviceMethods;
 
diff --git a/rust/hw/core/src/qdev.rs b/rust/hw/core/src/qdev.rs
index 87232becbad..f6037fbdcae 100644
--- a/rust/hw/core/src/qdev.rs
+++ b/rust/hw/core/src/qdev.rs
@@ -15,9 +15,9 @@
 use qom::{prelude::*, ObjectClass};
 use util::{Error, Result};
 
-pub use crate::bindings::{ClockEvent, DeviceClass, Property, ResetType};
+pub use crate::bindings::{ClockEvent, ResetType};
 use crate::{
-    bindings::{self, qdev_init_gpio_in, qdev_init_gpio_out, ResettableClass},
+    bindings::{self, qdev_init_gpio_in, qdev_init_gpio_out, DeviceClass, 
Property},
     irq::InterruptSource,
 };
 
@@ -206,6 +206,9 @@ pub trait DeviceImpl:
     }
 }
 
+#[repr(transparent)]
+pub struct ResettableClass(bindings::ResettableClass);
+
 unsafe impl InterfaceType for ResettableClass {
     const TYPE_NAME: &'static CStr =
         unsafe { 
CStr::from_bytes_with_nul_unchecked(bindings::TYPE_RESETTABLE_INTERFACE) };
@@ -214,23 +217,25 @@ unsafe impl InterfaceType for ResettableClass {
 impl ResettableClass {
     /// Fill in the virtual methods of `ResettableClass` based on the
     /// definitions in the `ResettablePhasesImpl` trait.
-    pub fn class_init<T: ResettablePhasesImpl>(&mut self) {
+    fn class_init<T: ResettablePhasesImpl>(&mut self) {
         if <T as ResettablePhasesImpl>::ENTER.is_some() {
-            self.phases.enter = Some(rust_resettable_enter_fn::<T>);
+            self.0.phases.enter = Some(rust_resettable_enter_fn::<T>);
         }
         if <T as ResettablePhasesImpl>::HOLD.is_some() {
-            self.phases.hold = Some(rust_resettable_hold_fn::<T>);
+            self.0.phases.hold = Some(rust_resettable_hold_fn::<T>);
         }
         if <T as ResettablePhasesImpl>::EXIT.is_some() {
-            self.phases.exit = Some(rust_resettable_exit_fn::<T>);
+            self.0.phases.exit = Some(rust_resettable_exit_fn::<T>);
         }
     }
 }
 
-impl DeviceClass {
-    /// Fill in the virtual methods of `DeviceClass` based on the definitions 
in
-    /// the `DeviceImpl` trait.
-    pub fn class_init<T: DeviceImpl>(&mut self) {
+pub trait DeviceClassExt {
+    fn class_init<T: DeviceImpl>(&mut self);
+}
+
+impl DeviceClassExt for DeviceClass {
+    fn class_init<T: DeviceImpl>(&mut self) {
         if <T as DeviceImpl>::REALIZE.is_some() {
             self.realize = Some(rust_realize_fn::<T>);
         }
diff --git a/rust/hw/core/src/sysbus.rs b/rust/hw/core/src/sysbus.rs
index 071fccff1e6..81fab3f1910 100644
--- a/rust/hw/core/src/sysbus.rs
+++ b/rust/hw/core/src/sysbus.rs
@@ -15,7 +15,7 @@
 use crate::{
     bindings,
     irq::{IRQState, InterruptSource},
-    qdev::{DeviceImpl, DeviceState},
+    qdev::{DeviceClassExt, DeviceImpl, DeviceState},
 };
 
 /// A safe wrapper around [`bindings::SysBusDevice`].
@@ -37,10 +37,14 @@ unsafe impl ObjectType for SysBusDevice {
 // TODO: add virtual methods
 pub trait SysBusDeviceImpl: DeviceImpl + IsA<SysBusDevice> {}
 
-impl SysBusDeviceClass {
+pub trait SysBusDeviceClassExt {
+    fn class_init<T: SysBusDeviceImpl>(&mut self);
+}
+
+impl SysBusDeviceClassExt for SysBusDeviceClass {
     /// Fill in the virtual methods of `SysBusDeviceClass` based on the
     /// definitions in the `SysBusDeviceImpl` trait.
-    pub fn class_init<T: SysBusDeviceImpl>(self: &mut SysBusDeviceClass) {
+    fn class_init<T: SysBusDeviceImpl>(&mut self) {
         self.parent_class.class_init::<T>();
     }
 }
diff --git a/rust/qom/src/prelude.rs b/rust/qom/src/prelude.rs
index 6a1ecaef2a7..1d1177f1e0d 100644
--- a/rust/qom/src/prelude.rs
+++ b/rust/qom/src/prelude.rs
@@ -4,6 +4,7 @@
 pub use crate::qom::IsA;
 pub use crate::qom::Object;
 pub use crate::qom::ObjectCast;
+pub use crate::qom::ObjectClassExt;
 pub use crate::qom::ObjectClassMethods;
 pub use crate::qom::ObjectDeref;
 pub use crate::qom::ObjectImpl;
diff --git a/rust/qom/src/qom.rs b/rust/qom/src/qom.rs
index 84455cea79b..cc00ddcfc98 100644
--- a/rust/qom/src/qom.rs
+++ b/rust/qom/src/qom.rs
@@ -729,10 +729,14 @@ pub trait ObjectImpl: ObjectType + IsA<Object> {
     T::UNPARENT.unwrap()(unsafe { state.as_ref() });
 }
 
-impl ObjectClass {
+pub trait ObjectClassExt {
+    fn class_init<T: ObjectImpl>(&mut self);
+}
+
+impl ObjectClassExt for ObjectClass {
     /// Fill in the virtual methods of `ObjectClass` based on the definitions 
in
     /// the `ObjectImpl` trait.
-    pub fn class_init<T: ObjectImpl>(&mut self) {
+    fn class_init<T: ObjectImpl>(&mut self) {
         if <T as ObjectImpl>::UNPARENT.is_some() {
             self.unparent = Some(rust_unparent_fn::<T>);
         }
-- 
2.52.0


Reply via email to