serde-rs / serde

Serialization framework for Rust
https://serde.rs/
Apache License 2.0
9.06k stars 767 forks source link

Enum Representations Internally tagged is Abigious for Tuple Structs #2693

Closed elibroftw closed 7 months ago

elibroftw commented 7 months ago

https://serde.rs/enum-representations.html#internally-tagged

There needs to be an example of a Tuple struct here. It's hard to infer how the following would look serialized.

#[derive(Serialize, Deserialize)]
#[serde(tag = "type")]
enum Message {
    Tuple(String)
}

Would this be serialized like this? I only guessed the content field from the "Adjacently tagged" section where content="c" was used.

{"type": "Tuple", "content" : "..." }

Or like this

["Tuple", "..."]
elibroftw commented 7 months ago

"cannot serialize tagged newtype variant XXXXXXX::Tuple containing a string"

Nice!

elibroftw commented 7 months ago

I believe the adjacent content needs to be before because otherwise it isn't clear that an error will occur

dtolnay commented 7 months ago

I think this is covered by the documentation section you linked to where it says:

This representation works for struct variants, newtype variants containing structs or maps, and unit variants but does not work for enums containing tuple variants.

Your enum has a newtype variant containing a string, which is not any of the supported cases.

kirit0s commented 1 week ago

The documentation says that this is a compilation error. But compilation done without errors.

Using a #[serde(tag = "...")] attribute on an enum containing a tuple variant is an error at compile time.

Mingun commented 1 week ago

The topicstarter used wrong name for his example. This is what is named "newtype" in serde. Tuple contains 0 or 2 or more elements

kirit0s commented 1 week ago

@Mingun Can you please provide example of enum with tuple variant, which is mentioned in the documentation?

kirit0s commented 1 week ago
#[derive(Serialize)]
#[serde(tag = "tag")]
enum A {
  VariantOne((i32, i32))
}

Also compile without errors.

Mingun commented 1 week ago
#[derive(Serialize)]
#[serde(tag = "tag")]
enum A {
  Tuple(i32, i32)
}
kirit0s commented 6 days ago

Ok, now I see compile error.

I wonder if it is possible to check at compile time, that newtype variants containing invalid type for serialize with internally tagged representation.

Mingun commented 6 days ago

Probably it is possible if introduce a set of traits and require that traits when deriving