Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LastElementNameNotAvailable error on writing #186

Open
rrichardson opened this issue Sep 29, 2022 · 13 comments
Open

LastElementNameNotAvailable error on writing #186

rrichardson opened this issue Sep 29, 2022 · 13 comments

Comments

@rrichardson
Copy link

rrichardson commented Sep 29, 2022

When attempting to serialize a struct, I get the error LastElementNameNotAvailable
Looking at the xml-rs code, that error is emitted after it fails to pop a name off of the stack.

https://github.com/netvl/xml-rs/blob/master/src/writer/emitter.rs#L351

So I'm guessing that it tried to call end_tag too many times?

I have these types (defined by the boto AWS s3 spec)

#[derive(Debug, Default, serde::Serialize, serde::Deserialize)]
#[derive(fake::Dummy)]
pub struct DeleteObjectsRequest {
    #[serde(skip)]
    pub bucket: BucketName,
    #[serde(skip)]
    pub bypass_governance_retention: Option<BypassGovernanceRetention>,
    #[serde(skip)]
    pub checksum_algorithm: Option<ChecksumAlgorithm>,
    pub delete: Delete,
    #[serde(skip)]
    pub expected_bucket_owner: Option<AccountId>,
    #[serde(skip)]
    pub mfa: Option<MFA>,
    #[serde(skip)]
    pub request_payer: Option<RequestPayer>,
}

// the relevant type is `Delete`  which is defined as 
#[derive(Debug, Default, serde::Serialize, serde::Deserialize)]
#[derive(fake::Dummy)]
pub struct Delete {
    pub objects: ObjectIdentifierList,
    pub quiet: Option<Quiet>,
}

#[derive(Debug, Default, serde::Serialize, serde::Deserialize)]
#[derive(fake::Dummy)]
pub struct ObjectIdentifier {
    pub key: ObjectKey,
    pub version_id: Option<ObjectVersionId>,
}
pub type ObjectIdentifierList = Vec<ObjectIdentifier>;
@rrichardson
Copy link
Author

Here is the debug output:

2022-09-29T18:27:21.520Z DEBUG [serde_xml_rs::ser] Struct DeleteObjectsRequest
2022-09-29T18:27:21.520Z DEBUG [serde_xml_rs::ser::map] field delete
2022-09-29T18:27:21.520Z DEBUG [serde_xml_rs::ser] Struct Delete
2022-09-29T18:27:21.520Z DEBUG [serde_xml_rs::ser::map] field objects
2022-09-29T18:27:21.520Z DEBUG [serde_xml_rs::ser] Sequence
2022-09-29T18:27:21.520Z DEBUG [serde_xml_rs::ser] Struct ObjectIdentifier
2022-09-29T18:27:21.520Z DEBUG [serde_xml_rs::ser::map] field key
2022-09-29T18:27:21.520Z DEBUG [serde_xml_rs::ser::map] end field
2022-09-29T18:27:21.520Z DEBUG [serde_xml_rs::ser::map] field version_id
2022-09-29T18:27:21.520Z DEBUG [serde_xml_rs::ser] Some
2022-09-29T18:27:21.520Z DEBUG [serde_xml_rs::ser::map] end field
2022-09-29T18:27:21.520Z DEBUG [serde_xml_rs::ser] Struct ObjectIdentifier
2022-09-29T18:27:21.520Z DEBUG [serde_xml_rs::ser::map] field key
2022-09-29T18:27:21.520Z DEBUG [serde_xml_rs::ser::map] end field
2022-09-29T18:27:21.520Z DEBUG [serde_xml_rs::ser::map] field version_id
2022-09-29T18:27:21.520Z DEBUG [serde_xml_rs::ser] None
2022-09-29T18:27:21.520Z DEBUG [serde_xml_rs::ser::map] end field
2022-09-29T18:27:21.520Z DEBUG [serde_xml_rs::ser] Struct ObjectIdentifier
2022-09-29T18:27:21.520Z DEBUG [serde_xml_rs::ser::map] field key
2022-09-29T18:27:21.520Z DEBUG [serde_xml_rs::ser::map] end field
2022-09-29T18:27:21.520Z DEBUG [serde_xml_rs::ser::map] field version_id
2022-09-29T18:27:21.520Z DEBUG [serde_xml_rs::ser] Some
2022-09-29T18:27:21.520Z DEBUG [serde_xml_rs::ser::map] end field

@burleight
Copy link

+1

There is a bug when serializing Vec's of struct or enum. I'm working on a fix.

burleight pushed a commit to burleight/serde-xml-rs that referenced this issue Sep 29, 2022
@duckfromdiscord
Copy link

I am having this issue now too, deserializing straight into a struct and converting it straight back gives this error. i do not get it when using serde_json::to_string, so it must be on serde-xml's end.

@gustavowd
Copy link

I am having tha same issue in this code:

use serde::{Deserialize, Serialize};
use serde_xml_rs::{from_str, to_string};

#[derive(Debug, Default, Deserialize, Serialize)]
struct Video {
id: u32,
title: String,
description: String,
removed: bool,
}

#[derive(Debug, Default, Deserialize, Serialize)]
struct Videos {
#[serde(rename = "Video")]
videos: Vec

fn main() {
//let file = File::open("videos.xml").expect("Unable to open file");
//let reader = BufReader::new(file);
//let videos: Videos = from_reader(reader).expect("Unable to parse XML");

//println!("Videos: {:?}", videos);

let xml_string = r#"
    <Videos>
        <Video>
            <id>1</id>
            <title>Video 1</title>
            <description>This is the first video.</description>
            <removed>false</removed>
        </Video>
        <Video>
            <id>2</id>
            <title>Video 2</title>
            <description>This is the second video.</description>
            <removed>true</removed>
        </Video>
    </Videos>
"#;

let videos: Videos = from_str(xml_string).unwrap();
println!("{:#?}", videos);

let xml_str_out = to_string(&videos).unwrap();
println!("{}", xml_str_out);

}

That's the error:
thread 'main' panicked at 'called Result::unwrap() on an Err value: Writer { source: LastElementNameNotAvailable }', src/main.rs:45:42

Any solution?

@mlappo
Copy link

mlappo commented Mar 1, 2023

I have exactly the same problem... Is there any workaround?
In general vector serializing works, but if the struct has rename-serialize then it's broken...

#[derive(Debug, Serialize, Deserialize, PartialEq)]
#[serde(rename(serialize = "some-parameter"))] /// !!! This is a problem, commenting this line makes it work, but produces wrong XML
struct SomeParameter {
    key: String,
    value: String,
}

#[derive(Debug, Serialize, Deserialize, PartialEq)]
#[serde(rename(serialize = "some-session"))]
struct SomeSession {
    #[serde(rename = "$value")]
    some_parameters: Vec<SomeParameter>,
}

@julienr
Copy link

julienr commented Mar 4, 2023

I managed to reduce it to this test case which fails for me on master:

#[test]
fn serialize_nested_collection() {
    #[derive(Debug, Serialize, PartialEq)]
    struct OuterCollection {
        a: Vec<A>,
    }

    #[derive(Debug, Serialize, PartialEq)]
    struct A {
        name: String,
    }

    let coll = OuterCollection {
        a: vec![A {
            name: "42".to_owned(),
        }],
    };

    let str = to_string(&coll).unwrap();
    println!("str={:?}", str);
}
running 1 test
thread 'serialize_nested_collection' panicked at 'called `Result::unwrap()` on an `Err` value: Writer { source: LastElementNameNotAvailable }', tests/test.rs:400:32
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
test serialize_nested_collection ... FAILED

julienr added a commit to julienr/serde-xml-rs that referenced this issue Mar 4, 2023
julienr added a commit to julienr/serde-xml-rs that referenced this issue Mar 5, 2023
duckfromdiscord added a commit to duckfromdiscord/serde-xml-rs that referenced this issue Apr 27, 2023
@oneslash
Copy link

Oookay, I used this use quick_xml::se::to_string; instead of current crate and works like a charm

@conqp
Copy link

conqp commented Jun 21, 2023

Thanks. I stumbled over this just now. It appears, that serde-xml-rs is dead.

@han1548772930
Copy link

I also have the same error

@gustavowd
Copy link

gustavowd commented Apr 8, 2024

@han1548772930, use the quick_xml library. Works like a charm.
Example:
Cargo.toml
[dependencies] serde = { version = "1.0", features = ["derive"] } quick-xml = {version = "0.31.0", features = ["serialize"]}

Code:
use serde::{Deserialize, Serialize};
use quick_xml::de::from_str as from_str;
use quick_xml::se::to_string as to_string;

#[derive(Debug, Default, Deserialize, Serialize)]
struct Video {
id: u32,
#[serde(rename = "Title")]
title: String,
description: String,
removed: bool,
}

#[derive(Debug, Default, Deserialize, Serialize)]
struct Videos {
#[serde(rename = "Video")]
videos: Vec<Video>,
}

fn main() {
let xml_string = r#"<Videos> <Video> <id>1</id> <Title>Video 1</Title> <description>This is the first video.</description> <removed>false</removed> </Video> <Video> <id>2</id> <Title>Video 2</Title> <description>This is the second video.</description> <removed>true</removed> </Video> </Videos>"#;

let videos: Videos = from_str(xml_string).unwrap();
println!("{:?}", videos);

let xml_str_out = to_string(&videos).unwrap();
println!("{}", xml_str_out);

@han1548772930
Copy link

han1548772930 commented Apr 9, 2024

@han1548772930, use the quick_xml library. Works like a charm. Example: Cargo.toml [dependencies] serde = { version = "1.0", features = ["derive"] } quick-xml = {version = "0.31.0", features = ["serialize"]}

Code: use serde::{Deserialize, Serialize}; use quick_xml::de::from_str as from_str; use quick_xml::se::to_string as to_string;

#[derive(Debug, Default, Deserialize, Serialize)] struct Video { id: u32, #[serde(rename = "Title")] title: String, description: String, removed: bool, }

#[derive(Debug, Default, Deserialize, Serialize)] struct Videos { #[serde(rename = "Video")] videos: Vec<Video>, }

fn main() { let xml_string = r#"<Videos> <Video> <id>1</id> <Title>Video 1</Title> <description>This is the first video.</description> <removed>false</removed> </Video> <Video> <id>2</id> <Title>Video 2</Title> <description>This is the second video.</description> <removed>true</removed> </Video> </Videos>"#;

let videos: Videos = from_str(xml_string).unwrap();
println!("{:?}", videos);

let xml_str_out = to_string(&videos).unwrap();
println!("{}", xml_str_out);

yes I have switched to quick_xml

@David-OConnor
Copy link

Thanks for the advice. I'm also hitting this; switching to quick-xml

@duckfromdiscord
Copy link

I needed serde-xml-rs, though, because the XML I was working with from another program required order to be maintained

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

10 participants