White-Oak / qml-rust

QML (Qt Quick) bindings for Rust language
MIT License
205 stars 18 forks source link

Deriving Q_OBJECT with Macros 1.1 #10

Open White-Oak opened 7 years ago

White-Oak commented 7 years ago

Since the release of the nightly macros 1.1 that should support custom derives on stable rust, I've been wondering if it would be possible and feasible to use them to derive Q_OBJECT, instead of using current inflexible macro Q_OBJECT!.

An example of deriving that would fully use conceived features:

#[derive(Q_OBJECT)]
#[signal(testname(a = "i32", b = "i32", f = "f32", d = "d64"))]
#[slot(launchGoose(i = "i32", launchText = "i32"))]
// you can specify the returned value if there's some
#[slot(gooseReport(), i32)]
#[slot(goose(), None)]
#[property(name, String, read = "get_name", write = "set_name", notify = "name_changed")]
// You can ask to generate names of rwn automatically
#[property(auto_names, String, read = "auto", write = "auto", notify = "auto")]
#[property(auto_names_all, String, rwn = "auto")]
#[property(read_only, String, read = "auto", write = "no", notify = "auto")]
// by default implementations of rwn methods is up to you, but you can ask to generate them for you
// Note that notify signal can't be generated as it is a signal and generated always
#[property(auto_names_generate, String, read = "auto(generate)", write = "auto(generate)", notify = "auto")]
#[property(auto_names_generate_all, String, rwn = "auto(generate)")]
// you can as well use your own names of course with generation
#[property(names_generate, String, read = "readName(generate)", write = "setName(generate)", notify = "nameChanged")]
// you can store properties in your structure if you want to
#[property(delegated, String, delegate, rwn = "auto")]
// you can as well delegate some or all of rwn methods to your own structure
#[property(delegated_some, String, delegate, read = "auto(generate)", write = "delegate", notify = "auto")]
#[property(delegated_all, String, delegate, rwn = "delegate")]
#[property(i, i32, rwn = "auto")]
#[property(i, f32, rwn = "auto")]
#[property(i, f64, rwn = "auto")]
struct Test;
White-Oak commented 7 years ago

The question is -- would it worth it? Or is it better to wait for Macros 1.2, which supposedly should support procedural macros.

rustonaut commented 7 years ago

The current macro might be a bit inflexible, but to be honest it is much more readable and intuitive then the alternative mentioned here.

On the other hand, with stringify!() it might be possible to create a Q_OBJECT! macro which maps to the macro 1.1 syntax shown above. (you can't really add #[...] attributes to a already defined struct so it's might not be the case)

From a design point of view I think the functionality exposed in this crate does much more than a #[derive(...)] (with properties) should ever do.

But then, the additional flexibility is nice. I think the main question here is, if this additional flexibility is needed (now)? And if it is worth the (from my pov) decrease in intuitiveness readability.

PS: You can also add this "flexibility" (at last partly) to the current Q_OBJECT! macro. But this tend to produce quite complex macro code, so I won't recommend it.

So in total I think it might be a good idea to wait for Macros 1.2, maybe even Macros 2.0 (depending on how long that would take, I'm not really up to date regarding the macro 2.0 development status). The idea would be to experiment more with QML/rust until then and then ship a first more stable release with the new (hopefully more hygenic etc.) macro system.

White-Oak commented 7 years ago

@dathinab Thanks for the input! Yes, I totally agree, that the readability is suffering with this alternative. However, if such flexibility would be required, there can be both custom derive and existing macro existing.

I agree with you that it might be a good idea to wait for procedural macros to come, I just wonder how long is the wait. Unfortunately, procedural macros is the thing rust developers would want to get right, so there is no hurry.

pythoneer commented 7 years ago

The only input i can give you about that is the perspective of the lib user. As i saw your example i am quit sure i like the macro syntax more.

White-Oak commented 7 years ago

@pythoneer yeah, I guess it's just got to wait for Macros 2.0. i hope it won't be a big wait.