-
Notifications
You must be signed in to change notification settings - Fork 108
Dart web: i64 fields in signals silently fail deserialization #672
Description
Bug
Any RustSignal struct containing i64 fields (e.g., Option<i64> for Unix-millis timestamps) silently fails deserialization on Dart web. The signal is sent successfully from Rust (send_signal_to_dart() returns Ok(())), but Dart never receives it.
Root cause
rinf uses serde-generate to produce Dart bindings. The Dart serde runtime's deserializeInt64() calls ByteData.getInt64() and serializeInt64() calls ByteData.setInt64() — both throw UnsupportedError on Dart web because JavaScript numbers are 64-bit doubles with no native 64-bit integer type.
The unsigned variant deserializeUint64() already uses a web-compatible BigInt path (_bytesToBigInt), but the signed deserializeInt64() does not.
The error occurs inside the assignRustSignal callback during bincodeDeserialize(), and is swallowed silently — no console error, no page error.
Fix
I've submitted a fix upstream: zefchain/serde-reflection#92
Once that's merged and released, updating the serde-generate dependency in rinf_cli will resolve this.
Workaround
Until the upstream fix is released, users can manually patch the generated lib/src/bindings/serde/binary_deserializer.dart after running rinf gen:
// Replace:
int deserializeInt64() {
final result = input.getInt64(_offset, Endian.little);
_offset += 8;
return result;
}
// With:
int deserializeInt64() {
final number = _bytesToBigInt(8, signed: true);
_offset += 8;
return number.toInt();
}And similarly for serializeInt64 in binary_serializer.dart.
Reproduction
- Define a signal with an
i64field:pub struct MySignal { pub timestamp: Option<i64> } - Send it from Rust on web:
MySignal { timestamp: Some(1711282800000) }.send_signal_to_dart() - Observe: Rust logs success, but Dart stream listener never fires
- Remove the
i64field → signal is received correctly
Environment
- rinf 8.10.0
- Flutter 3.38.x, Dart web (DDC debug mode)
- serde-generate 0.32.0