diff --git a/gio-subclass/tests/simple_application.rs b/gio-subclass/tests/simple_application.rs index 44e22fe..892ff50 100644 --- a/gio-subclass/tests/simple_application.rs +++ b/gio-subclass/tests/simple_application.rs @@ -1,6 +1,5 @@ // adaptation of https://gitlab.gnome.org/GNOME/glib/blob/master/gio/tests/gapplication-example-cmdline2.c use std::mem; -use std::ops; use std::ptr; use std::sync::{Once, ONCE_INIT}; @@ -17,6 +16,8 @@ use glib::prelude::*; use glib::translate::*; extern crate gio_subclass; + +#[macro_use] extern crate gobject_subclass; use gio_subclass::application::*; @@ -127,21 +128,8 @@ glib_wrapper! { } } -// TODO: This one should probably get a macro -impl ops::Deref for SimpleApplication { - type Target = imp::SimpleApplication; +gobject_subclass_deref!(SimpleApplication, Application); - fn deref(&self) -> &Self::Target { - unsafe { - let base: Application = from_glib_borrow(self.to_glib_none().0); - let imp = base.get_impl(); - let imp = imp.downcast_ref::().unwrap(); - // Cast to a raw pointer to get us an appropriate lifetime: the compiler - // can't know that the lifetime of base is the same as the one of self - &*(imp as *const imp::SimpleApplication) - } - } -} impl SimpleApplication { pub fn new<'a, I: Into>>( diff --git a/gobject-subclass/src/deref.rs b/gobject-subclass/src/deref.rs new file mode 100644 index 0000000..c68f590 --- /dev/null +++ b/gobject-subclass/src/deref.rs @@ -0,0 +1,25 @@ +#[macro_export] +macro_rules! gobject_subclass_deref( + ($name:ident, $base:ident) => { + gobject_subclass_deref!($name, imp::$name, $base); + }; + + ($name:ident, $target:ty, $base:ident) => { + use std::ops::Deref; + + impl Deref for $name { + type Target = $target; + + fn deref(&self) -> &Self::Target { + unsafe { + let base: $base = from_glib_borrow(self.to_glib_none().0); + let imp = base.get_impl(); + let imp = imp.downcast_ref::<$target>().unwrap(); + // Cast to a raw pointer to get us an appropriate lifetime: the compiler + // can't know that the lifetime of base is the same as the one of self + &*(imp as *const $target) + } + } + } + } +); diff --git a/gobject-subclass/src/lib.rs b/gobject-subclass/src/lib.rs index 6040c73..ab274af 100644 --- a/gobject-subclass/src/lib.rs +++ b/gobject-subclass/src/lib.rs @@ -23,3 +23,6 @@ pub mod guard; pub mod properties; #[macro_use] pub mod object; + +#[macro_use] +mod deref; diff --git a/gobject-subclass/tests/simple_object.rs b/gobject-subclass/tests/simple_object.rs index c92e610..05d28c4 100644 --- a/gobject-subclass/tests/simple_object.rs +++ b/gobject-subclass/tests/simple_object.rs @@ -7,7 +7,6 @@ // except according to those terms. use std::mem; -use std::ops; use std::ptr; use std::sync::{Once, ONCE_INIT}; @@ -19,6 +18,7 @@ extern crate glib; use glib::prelude::*; use glib::translate::*; +#[macro_use] extern crate gobject_subclass; use gobject_subclass::object::*; @@ -172,21 +172,7 @@ impl SimpleObject { } } -// TODO: This one should probably get a macro -impl ops::Deref for SimpleObject { - type Target = imp::SimpleObject; - - fn deref(&self) -> &Self::Target { - unsafe { - let base: Object = from_glib_borrow(self.to_glib_none().0); - let imp = base.get_impl(); - let imp = imp.downcast_ref::().unwrap(); - // Cast to a raw pointer to get us an appropriate lifetime: the compiler - // can't know that the lifetime of base is the same as the one of self - &*(imp as *const imp::SimpleObject) - } - } -} +gobject_subclass_deref!(SimpleObject, Object); #[test] fn test_create() {