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 FromVariant for Variant #679

Closed ids1024 closed 4 years ago

ids1024 commented 4 years ago

This is useful when combined with the container variant functions and trait implementations from https://github.com/gtk-rs/glib/pull/651.

Implementing ToVariant would be useful as well, but isn't currently possible: https://github.com/gtk-rs/glib/issues/678

sdroege commented 4 years ago

See https://github.com/gtk-rs/glib/issues/678#issuecomment-686967071 . Can you also add that here for symmetry? :)

valpackett commented 4 years ago

Trying to use the current implementation to access D-Bus property change notifications with their a{sv}:

    dd.connect_local("g-properties-changed", true, move |args| {
        let new_props = args[1]
            .get::<glib::Variant>()
            .unwrap()
            .unwrap()
            .get::<std::collections::HashMap<String, glib::Variant>>()
            .unwrap();
        None
    })

It does work now:

{"TimeToEmpty": Variant { ptr: 0x1eaedcbfd580, type: VariantTy { inner: "v" }, value: "<int64 19200>" }, "UpdateTime": Variant { ptr: 0x1eaed6ac0490, type: VariantTy { inner: "v" }, value: "<uint64 1599419489>" }, "EnergyRate": Variant { ptr: 0x1eaed6a8c260, type: VariantTy { inner: "v" }, value: "<5.6056000000000008>" }, "Energy": Variant { ptr: 0x1eaedcbd5890, type: VariantTy { inner: "v" }, value: "<29.9222>" }}

But I get the aforementioned "boxed" variants and there doesn't seem to be a way to access the inner variant in these, since the instances just return the outer variant itself :/ i.e. I can infinitely chain .get::<glib::Variant>().unwrap().get::<glib::Variant>().unwrap() uselessly

zeenix commented 4 years ago

But I get the aforementioned "boxed" variants and there doesn't seem to be a way to access the inner variant in these, since the instances just return the outer variant itself :/

You need to use the get_child_value() method.

valpackett commented 4 years ago

Oh. Thanks. idk why I keep staring at docs.rs for the release version expecting it to show something new from a PR.. (or from git from that matter) :D

valpackett commented 4 years ago

hmm..

thread 'main' panicked at 'assertion failed: ty.starts_with("a") || ty.starts_with("{") || ty.starts_with("(")', /home/greg/.local/share/cargo/git/checkouts/glib-53370c4288e47ffa/633b61a/src/variant.rs:197:9
valpackett commented 4 years ago

(using get_child_value to walk the a{sv} also gets me to these same variants with v inside)

(why do they exist?)

zeenix commented 4 years ago

thread 'main' panicked at 'assertion failed: ty.starts_with("a") || ty.starts_with("{") || ty.starts_with("(")', /home/greg/.local/share/cargo/git/checkouts/glib-53370c4288e47ffa/633b61a/src/variant.rs:197:9

Already fixed in master.

(using get_child_value to walk the a{sv} also gets me to these same variants with v inside)

(why do they exist?)

What?

zeenix commented 4 years ago

@sdroege sounds good to me.

FWIW, this is what I was doing in zvariant as well but @elmarco insisted that use of std traits rather than our own, was more important than a uniform API to deal with transformation of all types (including Variant itself) to/from Variant type. The huge drawback of not having a uniform API is that user has to be conscious of Variant boxing. So what I'm saying is that I believe this (PR) and custom traits is the best way forward!

valpackett commented 4 years ago

@zeenix the v variants were also fixed with the last push (ids1024 force-pushed the ids1024:from_variant branch from 633b61a to f6b61f3 11 hours ago) :+1: