RReverser / serde-xml-rs

xml-rs based deserializer for Serde (compatible with 1.0+)
https://crates.io/crates/serde-xml-rs
MIT License
270 stars 90 forks source link

I am unable to map some parts of vk.xml to serde #52

Open MaikKlein opened 7 years ago

MaikKlein commented 7 years ago

From the vulkan spec:

    <types comment="Vulkan type definitions">
        <type name="vk_platform" category="include">#include "vk_platform.h"</type>

            <comment>WSI extensions</comment>
        <type category="include">#include "<name>vulkan.h</name>"</type>
        <type category="include">#include &lt;<name>X11/Xlib.h</name>&gt;</type>
        <type category="include">#include &lt;<name>X11/extensions/Xrandr.h</name>&gt;</type>
        <type category="include">#include &lt;<name>android/native_window.h</name>&gt;</type>
        <type category="include">#include &lt;<name>mir_toolkit/client_types.h</name>&gt;</type>
        <type category="include">#include &lt;<name>wayland-client.h</name>&gt;</type>
        <type category="include">#include &lt;<name>windows.h</name>&gt;</type>
        <type category="include">#include &lt;<name>xcb/xcb.h</name>&gt;</type>

        <type requires="X11/Xlib.h" name="Display"/>
        <type requires="X11/Xlib.h" name="VisualID"/>
        <type requires="X11/Xlib.h" name="Window"/>
        <type requires="X11/extensions/Xrandr.h" name="RROutput"/>
        <type requires="android/native_window.h" name="ANativeWindow"/>
        <type requires="mir_toolkit/client_types.h" name="MirConnection"/>
        <type requires="mir_toolkit/client_types.h" name="MirSurface"/>
        <type requires="wayland-client.h" name="wl_display"/>
        <type requires="wayland-client.h" name="wl_surface"/>
        <type requires="windows.h" name="HINSTANCE"/>
        <type requires="windows.h" name="HWND"/>
        <type requires="windows.h" name="HANDLE"/>
        <type requires="windows.h" name="SECURITY_ATTRIBUTES"/>
        <type requires="windows.h" name="DWORD"/>
        <type requires="windows.h" name="LPCWSTR"/>
        <type requires="xcb/xcb.h" name="xcb_connection_t"/>
        <type requires="xcb/xcb.h" name="xcb_visualid_t"/>
        <type requires="xcb/xcb.h" name="xcb_window_t"/>

I have no idea how this would map to serde. I almost believe that this can not be expressed?

I am really confused, any help is greatly appreciated.

MaikKlein commented 7 years ago

I guess I can express is sort of like this

#[derive(Debug, Serialize, Deserialize)]
pub struct Types{
    #[serde(rename = "$value")]
    pub types: Vec<Type>,
    pub comment: String

}

#[derive(Debug, Serialize, Deserialize)]
pub enum Type{
    #[serde(rename = "type")]
    Type{
        category: Option<String>,
        name: String,
        requires: Option<String>,
    },
    #[serde(rename = "comment")]
    Comment(String)
}

But then I am missing the content in between <type> ... </type>.

Later I also get nested type.

        <type category="basetype">typedef <type>uint32_t</type> <name>VkSampleMask</name>;</type>
        <type category="basetype">typedef <type>uint32_t</type> <name>VkBool32</name>;</type>
        <type category="basetype">typedef <type>uint32_t</type> <name>VkFlags</name>;</type>
        <type category="basetype">typedef <type>uint64_t</type> <name>VkDeviceSize</name>;</type>

I assume I have to deserialize it manually?

terrybrash commented 7 years ago

Wow, what a coincidence. I'm also trying to write vulkan bindings generated from vk.xml and just ran into this problem.

RReverser commented 7 years ago

@MaikKlein Did you try other representations from https://serde.rs/enum-representations.html ? I would think in the worst case untagged should work (but one of tagged probably too).

terrybrash commented 7 years ago

In the simplest form, the type of xml that seemingly cannot be deserialized by serde-xml-rs looks like:

<sentence>Lorem <bold>ipsum</bold> dolor sit amet</sentence>

I thought this might work:

#[derive(Deserialize, Debug)]
pub struct Sentence {
    #[derive(rename="$value")]
    elements: Vec<SentenceElement>,
}

#[derive(Deserialize, Debug)]
#[serde(untagged)]
pub enum SentenceElement {
    Text(String),
    Bold {
        bold: String,
    },
}

But it errors with: Custom("missing field 'elements'")

I also tried various other ways without success.

terrybrash commented 7 years ago

Also, @MaikKlein, I found that other people had similar issues parsing vk.xml (along with some other gripes). So, somebody created an application to convert vk.xml into something saner: https://github.com/NicolBolas/New-Vulkan-XML-Format

It looks pretty good at first glance, and should be easily parsable by serde-xml-rs.

MaikKlein commented 7 years ago

@RReverser I actually haven't, I think that could be sufficient. But I am not sure if you can still parse things inside tags and between tags. <foo inside=""> between </foo>

@terrybrashaw We probably should join forces if we both want to just parse the vk.xml (or something similar). I need it for ash.

terrybrash commented 7 years ago

@MaikKlein Sure, I'll message you on Reddit so we can coordinate.

mloc commented 7 years ago

Was there any progress on this? I'm trying to parse something very similar, looks like this:

<obj file="byxml.dm:1">inner_text<obj file="byxml.dm:4">other_inner_text</obj></obj>
oli-obk commented 7 years ago

But it errors with: Custom("missing field 'elements'")

that sounds like a bug. We should never see the name elements in any errors if there is a rename attribute. If that issue is fixed, maybe your setup works?