gtk-rs / glib

DEPRECATED, use https://github.com/gtk-rs/gtk-rs-core repository instead!
http://gtk-rs.org/
MIT License
93 stars 62 forks source link

Implement ToVariant and FromVariant for Variant (not currently possible) #678

Closed ids1024 closed 4 years ago

ids1024 commented 4 years ago

With the new methods and trait implementations provided in https://github.com/gtk-rs/glib/pull/651, it seems like it would be helpful if Variant implemented ToVariant and FromVariant.

As a motivating example, consider this snippet trying to set a property with gdbus:

properties_proxy.call_sync::<gio::Cancellable>(
    "Set",
    Some(&("some-interface", "some-property", Variant::new_variant(&value)).to_variant()),
    gio::DBusCallFlags::NONE,
    60000,
    None,
)?;

This almost works, except the fact Variant::new_variant(&value) returns a Variant, which doesn't implement ToVariant. It's possible by passing a vector of variants to Variant::new_tuple, but it would be nice it the somewhat more ergonomic API were available.

Unfortunately, implementing ToVariant results in a compiler error:

error[E0119]: conflicting implementations of trait `std::convert::From<variant::Variant>` for type `variant::Variant`:
   --> src/variant.rs:526:1
    |
526 | impl<T: ToVariant> From<T> for Variant {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: conflicting implementation in crate `core`:
            - impl<T> std::convert::From<T> for T;

I can send a PR implementing FromVariant, since that doesn't pose an issue. But I'm not sure there's any way to support ToVariant on Variant, without new/unstable functionality in Rustc (specialization, negative trait bounds). Or some breaking changes to glib-rs which in some way would involve not having a impl<T: ToVariant> From<T> for Variant implementation.

ids1024 commented 4 years ago

While FromVariant allows things like this:

let ret: (HashMap<String, Variant>,) = proxy
    .call_sync::<gio::Cancellable>(
        "GetManagedObjects",
        None,
        gio::DBusCallFlags::NONE,
        60000,
        None,
    )
    .unwrap()
    .get()
    .unwrap();

Not sure if it would be strange for Variant to implement FromVariant but not ToVariant.

sdroege commented 4 years ago

Or some breaking changes to glib-rs which in some way would involve not having a impl<T: ToVariant> From<T> for Variant implementation.

That's what I would suggest. The From impl doesn't make much sense, that's why there's a separate trait already.