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

Flattened maps incorrectly (?) assumed to be maps #188

Closed
turion opened this issue Feb 10, 2020 · 9 comments
Closed

Flattened maps incorrectly (?) assumed to be maps #188

turion opened this issue Feb 10, 2020 · 9 comments

Comments

@turion
Copy link

turion commented Feb 10, 2020

Imagine a data format like this:

use serde::{Deserialize, Deserializer};

struct Foo {
    #[serde(flatten)]
    bar: Bar,
    #[serde(flatten)]
    baz: Baz,
}

struct Bar {
    thing: i64,
}

struct Baz {
    thingz: i64
}

These are nested structs, yes, but completely flattened, so they should be serializable to CSV. However, I get the following error:

Serialize: Error(Serialize("serializing maps is not supported, if you have a use case, please file an issue at https://github.com/BurntSushi/rust-csv"))

How can I work around this?

@BurntSushi
Copy link
Owner

Could you please provide a complete reproducible example that I can compile and run?

@turion
Copy link
Author

turion commented Feb 10, 2020

Yes, working on it. I'm also realizing that my issue might be a duplicate.

@turion
Copy link
Author

turion commented Feb 10, 2020

I don't know any better than this, which doesn't compile:

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=e1d23f7f696489fb347232c63ba4c69d

@turion
Copy link
Author

turion commented Feb 10, 2020

This is probably a duplicate of #98 and #155.

@BurntSushi
Copy link
Owner

Yes, this looks like a duplicate of #98. Thank you for writing out a more complete example.

@turion
Copy link
Author

turion commented Feb 10, 2020

One possible workaround is to use a tuple instead of a struct:

type Foo = (Bar, Baz);

struct Bar {
    thing: i64,
}

struct Baz {
    thingz: i64
}

@MixusMinimax
Copy link

MixusMinimax commented Mar 3, 2024

It's not a duplicate of #98, because this is specifically NOT a map. I would be a map if it weren't flattened, but it is.

struct A {
  #[serde(flatten)]
  b: B,
  z: i32,
}
struct B {
  x: i32,
  y: i32,
}

Is exactly the same as

struct A {
  x: i32,
  y: i32,
  z: i32,
}

when it comes to serialization, which is a valid and completely standard csv record.

This means, the error is a false positive.

The thing is, you don't HAVE to support hash maps, just structs is enough for basically all use cases.

@BurntSushi
Copy link
Owner

Serde still treats it as a map AIUI. Sorry, but Serde's flatten functionality probably doesn't work how you think it does. See also #354.

@MixusMinimax
Copy link

What I kind of mean is this:

The problem with flattening hashmaps is that the structure can change between records, making it a problem for writing the csv headers.

If you instead just kind of assume the first record to be representative of the entire dataset, that would be a problem.

With structs, that would not be a problem though, as you can just write the headers by using the first struct.

I guess this also means the field itself can't be optional... I know it's annoying, but I think it would be better than nothing. in my opinion

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

No branches or pull requests

3 participants