serde deserializer fails deserialize to untagged enums which has integer(i128) values
- Dominant language
- Rust
- Stars
- 34
- Forks
- 10
- PR merge metrics
- No merged PRs in 30d
Description
Similar to the issue previously reported on https://github.com/ipld/serde_ipld_dagcbor/pull/21, when trying to deserialize to an Internally tagged or Untagged `enum`, it seems that the `serde` internally calls `deserialize_any`, in which case `i128` is not supported.
The following test fails.
```rust
#[test]
fn ipld_deserializer_integer_untagged() {
#[derive(Clone, Debug, Deserialize, PartialEq)]
#[serde(untagged)]
enum MyEnum {
Foo { value: bool },
Bar { value: i32 },
}
// foo: OK
{
let ipld = Ipld::Map(BTreeMap::from([("value".into(), Ipld::Bool(true))]));
match MyEnum::deserialize(ipld) {
Ok(deserialized) => {
assert_eq!(deserialized, MyEnum::Foo { value: true });
}
Err(e) => {
panic!("{e:?}");
}
}
}
// bar: FAIL
{
let ipld = Ipld::Map(BTreeMap::from([("value".into(), Ipld::Integer(42))]));
match MyEnum::deserialize(ipld) {
Ok(deserialized) => {
assert_eq!(deserialized, MyEnum::Bar { value: 42 });
}
Err(e) => {
panic!("{e:?}");
}
}
}
}
```
```
SerdeError("invalid type: integer `42` as i128, expected any value")
```
I think this is a `serde`'s unresolved issue, so it may not be the responsibility of this library.
- https://github.com/serde-rs/json/issues/740
- https://github.com/serde-rs/serde/issues/1682
However, we can work around this problem by changing `Ipld::Integer` to have `i64` instead of `i128`.
my experimental branch:
https://github.com/sugyan/rust-ipld-core/commit/539530d6d9f20e9e34143d9a9d8f92375bbb0bf6
Since the IPLD specification requires minimum support for values up to 2^53, the change to i64 is destructive but still meets the specification.
https://ipld.io/design/tricky-choices/numeric-domain/#integers
Is it possible to change it so that, for example, "if a certain feature flag is specified, the Ipld::Integer of i64 is used"?
My background is that I am developing a library [`atrium`](https://github.com/sugyan/atrium), and I would like to provide a function to hold `unknown` values received from the server as an `Ipld` and deserialize them to an arbitrary type on the user side. However, I am having trouble converting from `Ipld` to other types due to this problem...
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.