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

Vec<String> inside of struct serializes incorrectly with serde #280

Closed
dralley opened this issue Mar 30, 2021 · 6 comments · Fixed by #490
Closed

Vec<String> inside of struct serializes incorrectly with serde #280

dralley opened this issue Mar 30, 2021 · 6 comments · Fixed by #490
Assignees
Labels
arrays Issues related to mapping XML content onto arrays using serde bug serde Issues related to mapping from Rust types to XML

Comments

@dralley
Copy link
Collaborator

dralley commented Mar 30, 2021

I was attempting to add quick-xml to the Rust serializer benchmarks and discovered that one of the complex benchmarks serialized incorrectly, resulting in errors on deserialization. The benchmark in question is the "minecraft savedata" benchmark.

I minimized it so it's less unwieldy. Here's a test case.

const RECIPES: [&'static str; 8] = [
    "pickaxe",
    "torch",
    "bow",
    "crafting table",
    "furnace",
    "shears",
    "arrow",
    "tnt",
];

#[derive(serde::Deserialize, serde::Serialize)]
pub struct RecipeBook {
    pub recipes: Vec<String>,
}

#[test]
fn test_fail_serialize() {
    let recipe_book = RecipeBook {
        recipes: RECIPES.iter().map(|s| s.to_string()).collect(),
    };

    let serialized = to_string(&recipe_book).unwrap();

    println!("{}", serialized);
    let deserialized: RecipeBook = from_str(&serialized).unwrap();
}

Prints the following when tests are run:

---- test_fail_serialize stdout ----
<RecipeBook recipes="pickaxetorchbowcrafting tablefurnaceshearsarrowtnt"/>
thread 'test_fail_serialize' panicked at 'called `Result::unwrap()` on an `Err` value: Custom("invalid type: string \"pickaxetorchbowcrafting tablefurnaceshearsarrowtnt\", expected a sequence")', tests/serde_roundtrip.rs:55:58
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

The problem is that recipes: Vec<String> and to_be_displayed: Vec<String> are being serialized into one long concatenated string and then assigned to an attribute of a self-closing element, rather than being serialized to a list of inner elements. Deserialize does the correct thing and expects a list of strings.

@dralley dralley changed the title Vec<String> inside of struct serializes improperly with serde Vec<String> inside of struct serializes incorrectly with serde Mar 31, 2021
dralley added a commit to dralley/quick-xml that referenced this issue Aug 11, 2021
@dralley
Copy link
Collaborator Author

dralley commented Aug 11, 2021

This may be related to #205

dralley added a commit to dralley/quick-xml that referenced this issue Aug 17, 2021
dralley added a commit to dralley/quick-xml that referenced this issue Aug 22, 2021
@shalinnijel2
Copy link

Is there a potential work around for this issue while this is still being worked on?

@shalinnijel2
Copy link

I guess using a custom serializer which uses serialize_field() is one option...

@Mingun Mingun added bug serde Issues related to mapping from Rust types to XML labels Jun 19, 2022
@zmrow
Copy link

zmrow commented Jul 28, 2022

I'm also wondering what the workaround is here... :)

@Mingun
Copy link
Collaborator

Mingun commented Jul 29, 2022

Workaround is to use a Newtype idiom:

#[test]
fn test_fail_serialize() {
    const RECIPES: [&'static str; 2] = [
        "pickaxe",
        "crafting table",
    ];

    #[derive(Debug, PartialEq, serde::Deserialize, serde::Serialize)]
    struct Workaround(String);

    #[derive(Debug, PartialEq, serde::Deserialize, serde::Serialize)]
    struct RecipeBook {
        recipes: Vec<Workaround>,
    }

    let recipe_book = RecipeBook {
        recipes: RECIPES.iter().map(|s| Workaround(s.to_string())).collect(),
    };

    let serialized = quick_xml::se::to_string(&recipe_book).unwrap();

    assert_eq!(serialized, "<RecipeBook><recipes>pickaxe</recipes><recipes>crafting table</recipes></RecipeBook>");

    let deserialized: RecipeBook = from_str(&serialized).unwrap();
    assert_eq!(deserialized, RecipeBook {
        recipes: RECIPES.iter().map(|s| Workaround(s.to_string())).collect(),
    });
}

@zmrow
Copy link

zmrow commented Jul 29, 2022

@Mingun Thanks so much!! 🎉

@Mingun Mingun added the arrays Issues related to mapping XML content onto arrays using serde label Aug 25, 2022
@Mingun Mingun self-assigned this Sep 7, 2022
Mingun added a commit to Mingun/quick-xml that referenced this issue Oct 1, 2022
Fixes tafia#252 - ok
Fixes tafia#280 - ok
Fixes tafia#287 - ok
Fixes tafia#343 - ok
Fixes tafia#346 - not ok
Fixes tafia#361 - ok
Partially addresses tafia#368
Fixes tafia#429 - ok
Fixes tafia#430 - ok
Mingun added a commit to Mingun/quick-xml that referenced this issue Oct 1, 2022
Fixes tafia#252
Fixes tafia#280
Fixes tafia#287
Fixes tafia#343
Fixes tafia#346
Fixes tafia#361
Partially addresses tafia#368
Fixes tafia#429
Fixes tafia#430
Mingun added a commit to Mingun/quick-xml that referenced this issue Oct 24, 2022
Fixes tafia#252
Fixes tafia#280
Fixes tafia#287
Fixes tafia#343
Fixes tafia#346
Fixes tafia#361
Partially addresses tafia#368
Fixes tafia#429
Fixes tafia#430

Fixes all tests
Mingun added a commit to Mingun/quick-xml that referenced this issue Oct 25, 2022
Fixes tafia#252
Fixes tafia#280
Fixes tafia#287
Fixes tafia#343
Fixes tafia#346
Fixes tafia#361
Partially addresses tafia#368
Fixes tafia#429
Fixes tafia#430

Fixes all tests
Mingun added a commit to Mingun/quick-xml that referenced this issue Oct 26, 2022
Fixes tafia#252
Fixes tafia#280
Fixes tafia#287
Fixes tafia#343
Fixes tafia#346
Fixes tafia#361
Partially addresses tafia#368
Fixes tafia#429
Fixes tafia#430

Fixes all tests

Co-authored-by: Daniel Alley <dalley@redhat.com>
JOSEPHGILBY pushed a commit to JOSEPHGILBY/quick-xml that referenced this issue Nov 5, 2022
Fixes tafia#252
Fixes tafia#280
Fixes tafia#287
Fixes tafia#343
Fixes tafia#346
Fixes tafia#361
Partially addresses tafia#368
Fixes tafia#429
Fixes tafia#430

Fixes all tests

Co-authored-by: Daniel Alley <dalley@redhat.com>
JOSEPHGILBY pushed a commit to JOSEPHGILBY/quick-xml that referenced this issue Nov 5, 2022
Fixes tafia#252
Fixes tafia#280
Fixes tafia#287
Fixes tafia#343
Fixes tafia#346
Fixes tafia#361
Partially addresses tafia#368
Fixes tafia#429
Fixes tafia#430

Fixes all tests

Co-authored-by: Daniel Alley <dalley@redhat.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
arrays Issues related to mapping XML content onto arrays using serde bug serde Issues related to mapping from Rust types to XML
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants