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

Deserializing u128 errors when inside an untagged enum #46

Open
uint opened this issue Nov 14, 2022 · 6 comments
Open

Deserializing u128 errors when inside an untagged enum #46

uint opened this issue Nov 14, 2022 · 6 comments

Comments

@uint
Copy link

uint commented Nov 14, 2022

Minimal reproducible example below. Note that the second you change u128 -> u64, the test passes.

#[derive(serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "snake_case", untagged)]
enum ExecuteMsg {
    Interface(Interface),
}

#[derive(serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "snake_case")]
enum Interface {
    IncreaseAllowance { amount: u128 },
}

#[test]
fn foo() {
    let foo = ExecuteMsg::Interface(Interface::IncreaseAllowance { amount: 777 });

    let foo_ser = serde_json_wasm::to_string(&foo).unwrap();

    let wrapper_de: ExecuteMsg = serde_json_wasm::from_str(&foo_ser).unwrap();
}
@uint
Copy link
Author

uint commented Nov 14, 2022

At a glance, this doesn't seem easily solvable. @hashedone any ideas?

@webmaster128
Copy link
Member

The error we are getting with the above test is

panicked at 'called Result::unwrap() on an Err value: Custom("data did not match any variant of untagged enum ExecuteMsg")', src/lib.rs:226:58

which is generated by serde: https://github.com/serde-rs/serde/blob/v1.0.147/serde_derive/src/de.rs#L1667-L1677. But I don't understand what those #attempts are and why this is failing.

The raw JSON is

{"increase_allowance":{"amount":"777"}}

which looks solid.

@uint
Copy link
Author

uint commented Nov 14, 2022

@webmaster128 In my investigation, I figured that when deserializing into an untagged enum serde first has to call deserialize_any to translate the input JSON into serde's representation. Then serde analyzes that to figure out which enum variant it matches. Or something along those lines.

The problem is there's no logic for deserialize_any to figure "this string I just found could be a string or it could be a u128".

@uint
Copy link
Author

uint commented Nov 21, 2022

I looked a bit deeper into serde macros and this might actually be due to serde's Content type (there's also this).

@webmaster128
Copy link
Member

I wonder if #54 solves this issue

@chipshort
Copy link

This is not fixed by #54.
It seems to be a serde bug. I get the same behaviour with serde_json.

While digging into it, I found these issues (and a few others that probably have the same root cause):
serde-rs/json#740
serde-rs/serde#1183

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

No branches or pull requests

3 participants