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

Untagged Enum Bug (?) #1155

Open
aramrw opened this issue Jul 8, 2024 · 1 comment
Open

Untagged Enum Bug (?) #1155

aramrw opened this issue Jul 8, 2024 · 1 comment

Comments

@aramrw
Copy link

aramrw commented Jul 8, 2024

pub type Entries = Vec<Vec<EntryItem>>;
// Untagged Enum is the issue
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(untagged)]
pub enum EntryItem {
    Str(String),
    Int(u128),
    ContentVec(Vec<serde_json::Value>),
}
[
    [
        "手信号",
        "てしんごう",
        "",
        "",
        0,
        [
            {
                "type": "structured-content",
                "content": [{/* long asf */}]
            }
        ]
     ]
]
Error("data did not match any variant of untagged enum EntryItem", line: 9, column: 8),
)
[src/main.rs:21:5] serde_json::from_str::<Entries2>(mystr) = Ok(
    [
        [
            Str(
                "手信号",
            ),
            Str(
                "てしんごう",
            ),
            Str(
                "",
            ),
            Str(
                "",
            ),
            ContentVec(
                Number(0),
            ),
            ContentVec(
                Array [
                    Object {
                        "content": String("[{/* long asf */}]"),
                        "type": String("structured-content"),
                    },
                ],
            ),
        ],
    ],
)

When the type is ContentVec(Vec<Value>), it throws the error above.
However, when I set ContentVec(Value) it deserializes fine?

Is that not a vector right after the 0 in the json?

And when I print it out the value as ContentVec(Value) instead of ContentVec(Vec<Value>), it is clearly an array:

Array [Object {
  "content": Object {
    "content": String("連ね歌"), 
    "href": String("?query=連ね歌&wildcards=off"), 
    "tag": String("a")}, 
    "type": String("structured-content")
  }
] 

I even added this if statement (when set as ContentVec(Value) ), to make sure it is an array.
Again, it prints out with no errors! (the same thing as above).

if let EntryItem::ContentVec(value) = &entry[5] {
    // This works
    if value.is_array() {
      println!("{x:?}")
    }
}

After asking a handful of people, everybody agreed this is not the intended behavior.
If it is, can I can get an explanation as to what is going on here...?

Please try the code out for yourself.
https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=6811facc5a4e83d7a46847f37da9d569

@jonasbb
Copy link

jonasbb commented Jul 8, 2024

I think this is caused by serde-rs/serde#2230. If you use u64 instead of u128 it works. You see that the Int(u128), variant of the enum is not being deserialized.

ContentVec(
    Number(0),
),

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

No branches or pull requests

2 participants