我的目标是取一个serde_json::Value::Number
,如果它包含的数字表示为一个非整数值,其小数部分为0.0
,则将其转换为包含等效整数表示的serde_json::Value::Number
。
我有下面的片段来尝试这一点:
use serde_json::{Number, Value};
fn trim_trailing_zeros(val: Value) -> Value {
match val {
Value::Number(n) => Value::Number({
match n.as_f64() {
Some(m) => {
if m.fract() == 0.0 {
Number::from(m as i64)
} else {
n
}
}
_ => n,
}
}),
var => var,
}
}
字符串
这样做的问题是,如果数字不能准确地转换为f64
,就像这个Rust Playground链接所显示的那样,输出不等于输入。这似乎是无法克服的,因为Number
的字段是私有的,所以我只能使用这几种方法,其中一种似乎是不可避免的as_f64
。其他方法似乎在这个问题中根本没用。
有没有人能想到另一种方法来做到这一点?有没有什么方法可以将Value::Number
转换为字符串,并尝试在不损失准确性的情况下解析它?
- 编辑:* 正如评论中所指出的,在尝试
as_f64()
之前,首先检查Number
是否包含i64
或f64
与is_i64()
或is_f64()
,理论上也可能遇到转换问题。
2条答案
按热度按时间d7v8vwbk1#
一种方法是使用
serde_json
的arbitrary_precision
特性。该特性将数字存储为字符串,然后您可以自己进行解析:个字符
操场
tvz2xvvm2#
如果你想不丢失浮点数,你应该考虑使用
rust_decimal::Decimal
。字符串
然后从
型
然后,您可以使用
.is_integer
区分整数和非整数,在使用.round
和.fract()
(或其他一些,如floor
和ceil
,取决于您的规则)进行数字化后,将分数部分和整数部分分开。