rust-decimal
rust-decimal copied to clipboard
serde float_roundtrip vs rust_decimal's serde-float
How does rust-decimal deserialize and serialize f64?
https://github.com/paupino/rust-decimal/blob/master/src/serde.rs#L342-L347
It seems like it calls to_string on f64.
serde json has a feature float_roundtrip
that enables perfect accuracy float parsing https://github.com/serde-rs/json/issues/536
How does it compare to what rust-decimal does?
It's a good question. Effectively Rust Decimal has different serialization/deserialization strategies that one can adopt to match their use case. serde-float
is one such strategy which causes the Rust Decimal library to use a very specific code path. Serde feature flags in Rust Decimal has become a bit complex for my liking but in general if only serde-float
is enabled (i.e. no arbitrary precision):
- Serializes using
serializer.serialize_f64(self.to_f64().unwrap())
- i.e. converts directly to a float without going through a string however is limited by what can fit inside af64
. - Deserializes using
Decimal::from_str(&value.to_string()).map_err(|_| E::invalid_value(Unexpected::Float(value), &self))
- i.e. it converts the value to a string and parses that directly into aDecimal
.
In contrast, it appears that the float_roundtrip
feature uses a form of lexical analysis to parse something looking like a float into a float. Not at all what rust_decimal
does for float deserialization.
If you're wanting to retain precision while parsing float like fields then I'd recommend serde-arbitrary-precision
to which leverages that feature flag on serde_json
. This can be used in combination with serde-float
so that serialization still outputs f64
. Unless there is a specific use case that float_roundtrip
is required?