Closed kujeger closed 1 year ago
Which JSON backend are you telling Seed to use - serde_json
or serde-wasm-bindgen
?
Whichever is the default; looks like serde-wasm-bindgen
Try serde_json
and see what happens. It'll probably fix it in the meantime, although swb
is supposed to have BigInt support :thinking:
Looks like I was wrong; according to https://docs.rs/crate/seed/latest/features serde-json
is the default.
Manually specifying serde-json
in features gives the same result. Using serde-wasm-bindgen
instead completely fails to deserialize the same numbers with this error:
JsonError(Serde(JsValue(Error: invalid type: floating point `12345678901234568`, expected i64
From Rust itself:
In: 9223372036854776000_i64
error: literal out of range for `i64`
--> src/main.rs:4:1
|
4 | 9223372036854776000_i64
| ^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[deny(overflowing_literals)]` on by default
= note: the literal `9223372036854776000_i64` does not fit into the type `i64` whose range is `-9223372036854775808..=9223372036854775807`
= help: consider using the type `u64` instead
but it does fit into u64
. Consider changing the number type that you're using, if you know that value can never be negative.
@kujeger I downloaded your example code and it just works.
From Rust itself:
In: 9223372036854776000_i64 error: literal out of range for `i64` --> src/main.rs:4:1 | 4 | 9223372036854776000_i64 | ^^^^^^^^^^^^^^^^^^^^^^^ | = note: `#[deny(overflowing_literals)]` on by default = note: the literal `9223372036854776000_i64` does not fit into the type `i64` whose range is `-9223372036854775808..=9223372036854775807` = help: consider using the type `u64` instead
but it does fit into
u64
. Consider changing the number type that you're using, if you know that value can never be negative.
To clarify, that was not the actual number I was attempting to deserialize when that error message was generated. The fetched payload was 9223372036854775807
, the precise i64 max. It was just an example of "too large" a number resulting a panic, presumably because the buggy behaviour rounded it upwards outside of the i64 limit.
@kujeger I downloaded your example code and it just works.
Could it be a platform issue? I've reproduced it across multiple machines and browsers (firefox and chromium), but they were all on linux. I don't have any windows or mac machines available for testing.
e: Just in case there's confusion, both buttons "work" in my example, but clicking the different buttons gives a different output below:
"Fetch data" -> Data: 1234567890, 12345678901234568, 1234567890123456800
"Fetch data using serde" -> Data: 1234567890, 12345678901234567, 1234567890123456789
The numbers seem to be rounded up due to precision loss in the "Fetch data" case.
I can reproduce the rounding behaviour with this:
let foo = 1234567890123456789_i64 as f64;
println!("{}", foo);
1234567890123456800
So it looks like fetch[..].json()
might be casting the numbers as f64 or something like that.
JS numbers are 53-bit, by the way.
obsolete since v0.10.0
Hi,
I discovered that when I was deserializing larger numbers in json payloads retrieved using
fetch
, there were off. If they are too large, deserialization completely fails with something likeJsonError(Serde(JsValue("invalid value: integer '9223372036854776000', expected i64 at line 1 column 70")))
.This is new with 0.9; it does not happen in 0.8.
Example based on the simple
fetch
example:After deserialization, the data has now become:
As you can see, something has gone wrong here.
As a workaround, manually deserializing the raw text using something like
works fine.
I put up a complete example runnable with
trunk serve
here: https://kujeger.net/dump/seed-json-deser-test.tar.gz