Repository: z-galaxy/zbus (Rust)

Issue:
xmlgen: Incorrect codegen with more complex type structures
In GitLab by @PolyMeilex on Mar 31, 2022, 12:20

Hi, I have a method like this one:
```xml
    <method name="GetAbcd">
      <arg type="u" name="a" direction="out" />
      <arg type="a((ssss)a(siiddada{sv})a{sv})" name="b" direction="out" />
      <arg type="a(iiduba(ssss)a{sv})" name="c" direction="out" />
      <arg type="a{sv}" name="d" direction="out" />
    </method>
```
After piping it into xmlgen I get this type as return value:
```rs
     (
        u32,
        Vec<(String, String, String, String)>,
        Vec<(
            i32,
            i32,
            f64,
            u32,
            bool,
            Vec<(String, String, String, String)>,
        )>,
        std::collections::HashMap<String, zbus::zvariant::OwnedValue>,
    )

```
There is several fields missing in this definition, here is the same type manually written by me to match what xml defines:
```rs
(
    u32,
    Vec<(
        (String, String, String, String),
        Vec<(
            String,
            i32,
            i32,
            f64,
            f64,
            Vec<f64>,
            HashMap<String, zbus::zvariant::OwnedValue>,
        )>,
        HashMap<String, zbus::zvariant::OwnedValue>,
    )>,
    Vec<(
        i32,
        i32,
        f64,
        u32,
        bool,
        Vec<(String, String, String, String)>,
        HashMap<String, zbus::zvariant::OwnedValue>,
    )>,
    HashMap<String, zbus::zvariant::OwnedValue>,
)
```


Discussion:
Thanks for reporting this. Wonder what happens. :thinking:
In GitLab by @TTWNO on Jul 23, 2022, 20:52

I've had a similar problems with the Collection.xml file from AT-SPI.

XML Source:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<node name="/node">
<interface name="org.a11y.atspi.Collection">
  <method name="GetMatches">
    <arg direction="in" name="rule" type="(aiia{ss}iaiiasib)"/>
    <annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="QSpiMatchRule"/>
    <arg direction="in" name="sortby" type="u"/>
    <arg direction="in" name="count" type="i"/>
    <arg direction="in" name="traverse" type="b"/>
    <arg direction="out" type="a(so)"/>
    <annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="QSpiReferenceSet"/>
  </method>
</interface>
</node>
```

Generated code:

```rust

#[dbus_proxy(interface = "org.a11y.atspi.Collection")]
trait Collection {
    /// GetMatches method
    fn get_matches(
        &self,
        rule: &(&[i32], i32, std::collections::HashMap<&str, &str>),
        sortby: u32,
        count: i32,
        traverse: bool,
    ) -> zbus::Result<Vec<(String, zbus::zvariant::OwnedObjectPath)>>;
}
```

I was able to set my methods up manually, but yes, @PolyMeilex , it's not just you.
Hi, I stumbled on this problem today, and dig a little to find out if it was easy to fix, and it was! I've opened the PR #506, however, I never contributed to an open source project, so I'm kinda lost on what I should do next.

Can someone give me some pointers on how to proceed? :thinking: 
> Hi, I stumbled on this problem today, and dig a little to find out if it was easy to fix, and it was! I've opened the PR #506,

Thanks so much. :pray: 

> however, I never contributed to an open source project, so I'm kinda lost on what I should do next.

Really? You did great and even followed the contributors guide to the letter. Most folks don't do it so well.

> Can someone give me some pointers on how to proceed? 🤔

What happens next is that I (and/or others) review the PR, possibly ask for changes before it can be merged. Once the changes are good and the CI passes (I've to approve the CI run manually for first contributors), I'll merge your PR.

Unless you wanted to contribute more? In which case, I've a [bunch of issues](https://github.com/dbus2/zbus/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) that could be good for new contributors to pick up.
> > Hi, I stumbled on this problem today, and dig a little to find out if it was easy to fix, and it was! I've opened the PR #506,
> 
> Thanks so much. 🙏 
> > however, I never contributed to an open source project, so I'm kinda lost on what I should do next.
> 
> Really? You did great and even followed the contributors guide to the letter. Most folks don't do it so well.

Thanks! Yeah, I didn't contributed to any open source before (other than for some friends projects), but I have some notions to try to look for standards and rules!

> > Can someone give me some pointers on how to proceed? 🤔
> 
> What happens next is that I (and/or others) review the PR, possibly ask for changes before it can be merged. Once the changes are good and the CI passes (I've to approve the CI run manually for first contributors), I'll merge your PR.

:+1: 

> Unless you wanted to contribute more? In which case, I've a [bunch of issues](https://github.com/dbus2/zbus/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) that could be good for new contributors to pick up.

Good to know! If I have the time I'll try to look into it!



Patch:
diff --git a/zbus_xmlgen/src/lib.rs b/zbus_xmlgen/src/lib.rs
index ad3021ea3..90400e1e8 100644
--- a/zbus_xmlgen/src/lib.rs
+++ b/zbus_xmlgen/src/lib.rs
@@ -228,7 +228,11 @@ fn to_rust_type(ty: &CompleteType, input: bool, as_ref: bool) -> String {
                 loop {
                     let c = it.peek().unwrap();
                     match **c as char {
-                        STRUCT_SIG_END_CHAR | DICT_ENTRY_SIG_END_CHAR => break,
+                        STRUCT_SIG_END_CHAR | DICT_ENTRY_SIG_END_CHAR => {
+                            // consume the closing character
+                            it.next().unwrap();
+                            break;
+                        }
                         _ => vec.push(iter_to_rust_type(it, input, false)),
                     }
                 }


Test patch:
diff --git a/zbus_xmlgen/tests/data/sample_object0.rs b/zbus_xmlgen/tests/data/sample_object0.rs
index 67d50a15b..03b357f88 100644
--- a/zbus_xmlgen/tests/data/sample_object0.rs
+++ b/zbus_xmlgen/tests/data/sample_object0.rs
@@ -1,6 +1,9 @@
 #[dbus_proxy(interface = "com.example.SampleInterface0", assume_defaults = true)]
 trait SampleInterface0 {
 
+    /// BarplexSig method
+    fn barplex_sig(&self, rule: &(&[i32], i32, std::collections::HashMap<&str, &str>, i32, &[i32], i32, &[&str], i32, bool)) -> zbus::Result<Vec<(String, zbus::zvariant::OwnedObjectPath)>>;
+
     /// Bazify method
     fn bazify(&self, bar: &(i32, i32, u32)) -> zbus::Result<zbus::zvariant::OwnedValue>;
 
diff --git a/zbus_xmlgen/tests/data/sample_object0.xml b/zbus_xmlgen/tests/data/sample_object0.xml
index ec53891b0..6f2e4dcf6 100644
--- a/zbus_xmlgen/tests/data/sample_object0.xml
+++ b/zbus_xmlgen/tests/data/sample_object0.xml
@@ -17,6 +17,10 @@
      <method name="MogrifyMe">
        <arg name="bar" type="(iiav)" direction="in"/>
      </method>
+     <method name="BarplexSig">
+       <arg direction="in" name="rule" type="(aiia{ss}iaiiasib)"/>
+       <arg direction="out" type="a(so)"/>
+     </method>
      <signal name="Changed">
        <arg name="new_value" type="b"/>
      </signal>