fix(query): preserve arbitrary precision integers

This commit is contained in:
t8y2 2026-07-27 22:51:13 +08:00
parent 146dc672dd
commit 2ba41f71ae
No known key found for this signature in database
1 changed files with 49 additions and 1 deletions

View File

@ -84,7 +84,12 @@ pub fn json_value_for_js(value: serde_json::Value) -> serde_json::Value {
} else if let Some(value) = number.as_u64() {
safe_u64_to_json(value)
} else {
serde_json::Value::Number(number)
let value = number.to_string();
if value.bytes().all(|byte| byte == b'-' || byte.is_ascii_digit()) {
serde_json::Value::String(value)
} else {
serde_json::Value::Number(number)
}
}
}
serde_json::Value::Array(values) => {
@ -172,4 +177,47 @@ mod tests {
fn binary_values_are_displayed_as_prefixed_hex() {
assert_eq!(binary_value_to_json(&[0x00, 0x01, 0xab, 0xff]), serde_json::json!("0x0001abff"));
}
#[test]
fn arbitrary_precision_integers_are_strings_for_js() {
let value = serde_json::from_str(
r#"{
"positive": 20240302001417986771,
"negative": -20240302001417986771
}"#,
)
.unwrap();
assert_eq!(
json_value_for_js(value),
serde_json::json!({
"positive": "20240302001417986771",
"negative": "-20240302001417986771"
})
);
}
#[test]
fn json_value_for_js_preserves_existing_value_behavior_recursively() {
let value = serde_json::from_str(
r#"{
"safe": [9007199254740991, -9007199254740991],
"unsafe": [9007199254740992, -9007199254740992],
"non_integer": [1.25, 1e-2],
"other": [null, true, "text"]
}"#,
)
.unwrap();
let expected: serde_json::Value = serde_json::from_str(
r#"{
"safe": [9007199254740991, -9007199254740991],
"unsafe": ["9007199254740992", "-9007199254740992"],
"non_integer": [1.25, 1e-2],
"other": [null, true, "text"]
}"#,
)
.unwrap();
assert_eq!(json_value_for_js(value), expected);
}
}