diff --git a/crates/dbx-core/src/db/mod.rs b/crates/dbx-core/src/db/mod.rs index fda73dd09..ebf99ceaf 100644 --- a/crates/dbx-core/src/db/mod.rs +++ b/crates/dbx-core/src/db/mod.rs @@ -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); + } }