Skip to content

Commit 195048a

Browse files
committed
Add #[derive(QEnum)]
see rust-lang/rust#8730
1 parent 7603e50 commit 195048a

File tree

5 files changed

+257
-23
lines changed

5 files changed

+257
-23
lines changed

qmetaobject/src/lib.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,22 @@ pub trait QGadget {
409409
Self: Sized;
410410
}
411411

412+
/// Trait that is implemented by the QEnum custom derive macro
413+
///
414+
/// Do not implement this trait yourself, use `#[derive(QEnum)]`.
415+
pub trait QEnum {
416+
/// Returns a pointer to a meta object
417+
fn static_meta_object() -> *const QMetaObject
418+
where
419+
Self: Sized;
420+
421+
fn from_raw_value(raw: i32) -> Option<Self>
422+
where
423+
Self: Sized;
424+
425+
fn to_raw_value(&self) -> i32;
426+
}
427+
412428
#[doc(hidden)]
413429
#[no_mangle]
414430
pub unsafe extern "C" fn RustObject_metaObject(p: *mut RefCell<QObject>) -> *const QMetaObject {
@@ -445,7 +461,8 @@ pub struct QMetaObject {
445461
pub superdata: *const QMetaObject,
446462
pub string_data: *const u8,
447463
pub data: *const u32,
448-
pub static_metacall: extern "C" fn(o: *mut c_void, c: u32, idx: u32, a: *const *mut c_void),
464+
pub static_metacall:
465+
Option<extern "C" fn(o: *mut c_void, c: u32, idx: u32, a: *const *mut c_void)>,
449466
pub r: *const c_void,
450467
pub e: *const c_void,
451468
}

qmetaobject/src/qtdeclarative.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,27 @@ pub fn qml_register_type<T: QObject + Default + Sized>(
239239
})}
240240
}
241241

242+
/// Register the given enum as a QML type
243+
///
244+
/// Refer to the Qt documentation for qmlRegisterUncreatableMetaObject.
245+
pub fn qml_register_enum<T: QEnum>(
246+
uri: &std::ffi::CStr,
247+
version_major: u32,
248+
version_minor: u32,
249+
qml_name: &std::ffi::CStr,
250+
)
251+
{
252+
let uri_ptr = uri.as_ptr();
253+
let qml_name_ptr = qml_name.as_ptr();
254+
let meta_object = T::static_meta_object();
255+
256+
unsafe { cpp!([qml_name_ptr as "char*", uri_ptr as "char*", version_major as "int",
257+
version_minor as "int", meta_object as "const QMetaObject *"]{
258+
qmlRegisterUncreatableMetaObject(*meta_object, uri_ptr, version_major,
259+
version_minor, qml_name_ptr, "Access to enums & flags only");
260+
})}
261+
}
262+
242263
/// A QObject-like trait to inherit from QQuickItem.
243264
///
244265
/// Work in progress

qmetaobject/tests/tests.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -606,3 +606,44 @@ fn panic_when_moved_setter() {
606606
do_test(my_obj, "Item { function doTest() { _obj.prop_y = 45; } }");
607607
}
608608
*/
609+
610+
#[derive(QEnum)]
611+
#[repr(u8)]
612+
enum MyEnum {
613+
None,
614+
First = 1,
615+
Four = 4,
616+
}
617+
618+
#[derive(QObject, Default)]
619+
struct MyEnumObject {
620+
base: qt_base_class!(trait QObject),
621+
}
622+
623+
#[test]
624+
fn enum_properties() {
625+
qml_register_enum::<MyEnum>(
626+
CStr::from_bytes_with_nul(b"MyEnumLib\0").unwrap(),
627+
1,
628+
0,
629+
CStr::from_bytes_with_nul(b"MyEnum\0").unwrap(),
630+
);
631+
let my_obj = MyObject::default();
632+
assert!(do_test(
633+
my_obj,
634+
"import MyEnumLib 1.0
635+
Item {
636+
function doTest() {
637+
if(MyEnum.None != 0) {
638+
return false;
639+
}
640+
if(MyEnum.First != 1) {
641+
return false;
642+
}
643+
if(MyEnum.Four != 4) {
644+
return false;
645+
}
646+
return true;
647+
}}"
648+
));
649+
}

qmetaobject_impl/src/lib.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,12 @@ pub fn qgadget_impl(input: TokenStream) -> TokenStream {
7070
qobject_impl::generate(input, false)
7171
}
7272

73+
/// Implementation of #[derive(QEnum)]
74+
#[proc_macro_derive(QEnum, attributes(QMetaObjectCrate))]
75+
pub fn qenum_impl(input: TokenStream) -> TokenStream {
76+
qobject_impl::generate_enum(input)
77+
}
78+
7379
/// Implementation of the qmetaobject::qrc! macro
7480
#[proc_macro]
7581
pub fn qrc_internal(input: TokenStream) -> TokenStream {

0 commit comments

Comments
 (0)