ImJeremyHe / xmlserde

A user-friendly Rust library for serializing or deserializing the XML files
20 stars 2 forks source link

Fails to use a struct for an attribute #32

Closed bilelmoussaoui closed 4 months ago

bilelmoussaoui commented 5 months ago

I am trying to parse an xml file that has various version attributes, so I want to create a wrapper struct pub struct Version(String); and use that instead of just an alias which would work fine.

Given the following xml

<repository xmlns="http://www.gtk.org/introspection/core/1.0" xmlns:c="http://www.gtk.org/introspection/c/1.0" xmlns:glib="http://www.gtk.org/introspection/glib/1.0" version="1.2">
</repository>

The following code should work

#[derive(Debug, XmlDeserialize)]
#[xmlserde(root = b"repository")]
pub struct Repository {
    #[xmlserde(name = b"version", ty = "attr")]
    version: Version,
}

#[derive(Debug, XmlDeserialize)]
pub struct Version {
    #[xmlserde(ty = "text")]
    inner: String,
}

Instead the code fails to compile with

error[E0061]: this function takes 4 arguments but 1 argument was supplied
   --> src/parser/repository.rs:20:17
    |
20  | #[derive(Debug, XmlDeserialize)]
    |                 ^^^^^^^^^^^^^^
    |                 |
    |                 expected `&[u8]`, found `&String`
    |                 three arguments of type `&mut Reader<_>`, `Attributes<'_>`, and `bool` are missing
    |
    = note: expected reference `&[u8]`
               found reference `&String`
note: associated function defined here
   --> /home/bilalelmoussaoui/.cargo/registry/src/index.crates.io-6f17d22bba15001f/xmlserde-0.7.0/src/lib.rs:183:8
    |
183 |     fn deserialize<B: BufRead>(
    |        ^^^^^^^^^^^
    = note: this error originates in the derive macro `XmlDeserialize` (in Nightly builds, run with -Z macro-backtrace for more info)
help: provide the arguments
    |
20  | #[derive(Debug, XmlDeserialize(/* &[u8] */, /* reader */, /* Attributes<'_> */, /* bool */))]
    |                               +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

error[E0308]: mismatched types
  --> src/parser/repository.rs:20:17
   |
20 | #[derive(Debug, XmlDeserialize)]
   |                 ^^^^^^^^^^^^^^
   |                 |
   |                 expected `Version`, found `Result<_, _>`
   |                 this expression has type `Version`
   |
   = note: expected struct `Version`
                found enum `Result<_, _>`
   = note: this error originates in the derive macro `XmlDeserialize` (in Nightly builds, run with -Z macro-backtrace for more info)
ImJeremyHe commented 5 months ago

@bilelmoussaoui Hey! Thank you for you report and sorry for the poor documents.

Since here Version is an attribute so it should be a XmlValue. (I think) All of the builtin types have been implemented, so you can use it directly.

    #[test]
    fn test_issue32() {
        type Version = String;

        #[derive(Debug, XmlDeserialize)]
        #[xmlserde(root = b"repository")]
        pub struct Repository {
            #[xmlserde(name = b"version", ty = "attr")]
            version: Version,
        }

        let xml = r#"<repository xmlns="http://www.gtk.org/introspection/core/1.0" xmlns:c="http://www.gtk.org/introspection/c/1.0" xmlns:glib="http://www.gtk.org/introspection/glib/1.0" version="1.2"></repository>"#;
        let repo = xml_deserialize_from_str::<Repository>(&xml).unwrap();
        assert_eq!(repo.version, "1.2");
    }
bilelmoussaoui commented 5 months ago

What you are using here is an alias, type Version = String and not a struct Version(String);, can it work in this case?

Thanks for the quick reply

ImJeremyHe commented 5 months ago

@bilelmoussaoui Oh yes. Now the struct or enum is not designed to be used in attributes (and I think this is an effective way to keep the process of serializing/deserializing understandable). So no available proc macro for it. If you still want to do so, then you have to implement the XmlValue for your own structs

bilelmoussaoui commented 5 months ago

Oh I see! Yes, implementing the trait makes the error go away and everything works flawlessly. Should I go ahead and close this issue or do you want to keep it open for either documentation purposes or to improve the reported error message from the XmlDeserialize macro?