dbus2 / zbus

Rust D-Bus crate.
Other
385 stars 88 forks source link

xmlgen: Bad code generated for org.gtk.Actions.Changed signal #412

Closed jaskij closed 7 months ago

jaskij commented 1 year ago

Seems to be a return of #149, or something similar.

Using the files from #411, I am getting:

   --> src/cog.rs:24:1
    |
24  | #[dbus_proxy(interface = "org.gtk.Actions", assume_defaults = true)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Deserialize<'_>` is not implemented for `&[&str]`

and

error[E0277]: the trait bound `&[zbus::zvariant::Value<'_>]: Deserialize<'_>` is not satisfied
   --> src/cog.rs:24:1
    |
24  | #[dbus_proxy(interface = "org.gtk.Actions", assume_defaults = true)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Deserialize<'_>` is not implemented for `&[zbus::zvariant::Value<'_>]`

Relevant XML excerpt:

    <signal name="Changed">
      <arg type="as" name="removals">
      </arg>
      <arg type="a{sb}" name="enable_changes">
      </arg>
      <arg type="a{sv}" name="state_changes">
      </arg>
      <arg type="a{s(bgav)}" name="additions">
      </arg>
    </signal>

generated function:

    /// Changed signal
    #[dbus_proxy(signal)]
    fn changed(
        &self,
        removals: &[&str],
        enable_changes: std::collections::HashMap<&str, bool>,
        state_changes: std::collections::HashMap<&str, zbus::zvariant::Value<'_>>,
        additions: std::collections::HashMap<
            &str,
            (bool, zbus::zvariant::Signature<'_>, &[zbus::zvariant::Value<'_>]),
        >,
    ) -> zbus::Result<()>;
AndreaRicchi commented 11 months ago

The same problem generating the net.Connman.Manager:

        <signal name="ServicesChanged">
            <arg type="a(oa{sv})" name="changedServiceList"/>
            <arg type="ao" name="deletedService"/>
        </signal>

to:

    /// ServicesChanged signal
    #[dbus_proxy(signal)]
    fn services_changed(
        &self,
        changedServiceList: &[(
            zbus::zvariant::ObjectPath<'_>,
            std::collections::HashMap<&str, zbus::zvariant::Value<'_>>,
        )],
        deletedService: &[zbus::zvariant::ObjectPath<'_>],
    ) -> zbus::Result<()>;

with error:

error[E0277]: the trait bound `&[(zbus::zvariant::ObjectPath<'_>, HashMap<&str, zbus::zvariant::Value<'_>>)]: Deserialize<'_>` is not satisfied
   --> src/manager.rs:15:1
    |
15  | #[dbus_proxy(interface = "net.connman.Manager", assume_defaults = true)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Deserialize<'_>` is not implemented for `&[(zbus::zvariant::ObjectPath<'_>, HashMap<&str, zbus::zvariant::Value<'_>>)]`
    |
    = help: the following other types implement trait `Deserialize<'de>`:
              [T; 0]
              [T; 1]
              [T; 2]
              [T; 3]
              [T; 4]
              [T; 5]
              [T; 6]
              [T; 7]
            and 26 others
    = note: required for `(&[(zbus::zvariant::ObjectPath<'_>, HashMap<&str, zbus::zvariant::Value<'_>>)], &[zbus::zvariant::ObjectPath<'_>])` to implement `Deserialize<'_>`
    = note: required for `(&[(zbus::zvariant::ObjectPath<'_>, HashMap<&str, zbus::zvariant::Value<'_>>)], &[zbus::zvariant::ObjectPath<'_>])` to implement `DynamicDeserialize<'_>`
note: required by a bound in `zbus::Message::body`
   --> /home/rcc/.cargo/registry/src/index.crates.io-6f17d22bba15001f/zbus-3.14.1/src/message.rs:395:12
    |
393 |     pub fn body<'d, 'm: 'd, B>(&'m self) -> Result<B>
    |            ---- required by a bound in this associated function
394 |     where
395 |         B: zvariant::DynamicDeserialize<'d>,
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Message::body`
    = note: this error originates in the attribute macro `dbus_proxy` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: the trait bound `&[zbus::zvariant::ObjectPath<'_>]: Deserialize<'_>` is not satisfied
   --> src/manager.rs:15:1
    |
15  | #[dbus_proxy(interface = "net.connman.Manager", assume_defaults = true)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Deserialize<'_>` is not implemented for `&[zbus::zvariant::ObjectPath<'_>]`
    |
    = help: the following other types implement trait `Deserialize<'de>`:
              [T; 0]
              [T; 1]
              [T; 2]
              [T; 3]
              [T; 4]
              [T; 5]
              [T; 6]
              [T; 7]
            and 26 others
    = note: required for `(&[(zbus::zvariant::ObjectPath<'_>, HashMap<&str, zbus::zvariant::Value<'_>>)], &[zbus::zvariant::ObjectPath<'_>])` to implement `Deserialize<'_>`
    = note: required for `(&[(zbus::zvariant::ObjectPath<'_>, HashMap<&str, zbus::zvariant::Value<'_>>)], &[zbus::zvariant::ObjectPath<'_>])` to implement `DynamicDeserialize<'_>`
note: required by a bound in `zbus::Message::body`
   --> /home/rcc/.cargo/registry/src/index.crates.io-6f17d22bba15001f/zbus-3.14.1/src/message.rs:395:12
    |
393 |     pub fn body<'d, 'm: 'd, B>(&'m self) -> Result<B>
    |            ---- required by a bound in this associated function
394 |     where
395 |         B: zvariant::DynamicDeserialize<'d>,
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Message::body`
    = note: this error originates in the attribute macro `dbus_proxy` (in Nightly builds, run with -Z macro-backtrace for more info)

For more information about this error, try `rustc --explain E0277`.
error: could not compile `rconnman_zbus` (bin "rconnman_zbus") due to 2 previous errors
zeenix commented 11 months ago

As I wrote in the duplicate (#487): The question would be if we can support this (I'd like that, if possible) or fix xmlgen to produce working code.

jaskij commented 11 months ago

Coming back to this, thanks to the recent traffic, those are signals - we are receiving data.

I haven't used the server side of zbus, but how are regular methods implemented there? The simplest solution might be for xmlgen to use the server method codegen for client signal callbacks.

zeenix commented 11 months ago

I haven't used the server side of zbus, but how are regular methods implemented there? The simplest solution might be for xmlgen to use the server method codegen for client signal callbacks.

I'm not sure what you mean. There are no callbacks on the client-side and until #236 is addressed (not happening in the upcoming 4.x at least, unless someone else does the work), dbus_proxy and dbus_interface don't share much.

jaskij commented 11 months ago

If there are no callbacks, then how are signals even implemented on the client side? It might also be a difference in semantics - to me fn changed() in my OP is a callback.

(if I remember correctly, I haven't looked at DBus in a good long while, so I might have the whole terminology wrong - for example, I don't even remember what proxies and interfaces are responsible for in zbus)

zeenix commented 11 months ago

If there are no callbacks, then how are signals even implemented on the client side? It might also be a difference in semantics - to me fn changed() in my OP is a callback.

Through streams. The macro generates API to create streams for each signal.

(if I remember correctly, I haven't looked at DBus in a good long while, so I might have the whole terminology wrong - for example, I don't even remember what proxies and interfaces are responsible for in zbus)

I'd suggest to read our book, which explains the essential D-Bus concepts and use of both macros.

zeenix commented 11 months ago

@jaskij could you please try recreating this with our main branch? There was a similar issue recently fixed.

zeenix commented 9 months ago

Seems to be a return of #149, or something similar.

I just realized that #149 fix hasn't yet gone into a release and hence why you might be seeing this. Hopefully it will be released soon (this week). Please test that (or the git main already) and if you can still reproduce, please comment here and I'll reopen the issue.

hdonnay commented 7 months ago

I'm seeing this in zbus 4.1.2:

error[E0277]: the trait bound `&[&str]: Deserialize<'_>` is not satisfied
  --> src/eds.rs:22:1
   |
22 | / #[proxy(
23 | |     interface = "org.gnome.evolution.dataserver.Calendar",
24 | |     default_service = "org.gnome.evolution.dataserver.Calendar8",
25 | |     gen_blocking = false,
26 | |     assume_defaults = true
27 | | )]
   | |__^ the trait `Deserialize<'_>` is not implemented for `&[&str]`
   |
   = help: the following other types implement trait `Deserialize<'de>`:
             [T; 0]
             [T; 1]
             [T; 2]
             [T; 3]
             [T; 4]
             [T; 5]
             [T; 6]
             [T; 7]
           and 26 others
   = note: required for `&[&str]` to implement `DynamicDeserialize<'_>`
note: required by a bound in `Body::deserialize`
zeenix commented 7 months ago

I'm seeing this in zbus 4.1.2:

Thanks. I can reproduce this locally. This looks like the opposite issue (and may have been caused by the solution to this issue) even though we end up with the same message.

zeenix commented 7 months ago

@hdonnay Although I added a test for your exact use case in #691, it never hurts to double-check if the issue was really fixed by the PR. :)

hdonnay commented 7 months ago

It certainly looks right. I'll try to find time to build a new xmlgen and check.

zeenix commented 7 months ago

It certainly looks right. I'll try to find time to build a new xmlgen and check.

Thanks. Since I added the testcase, I am fairly certain that it at least solves you particular issue, so I rolled out a new xmlgen release.