// JSON 参照独立实现 Serde 的 Decimal 字符串合同,复用同一个 serde_json 解析器。 impl serde::Serialize for NativeDisplay { fn serialize( &self, encoder: Encoder, ) -> Result { encoder.collect_str(self) } } impl<'input> serde::Deserialize<'input> for NativeDisplay { fn deserialize>( decoder: Decoder, ) -> Result { struct Visitor; impl<'input> serde::de::Visitor<'input> for Visitor { type Value = NativeDisplay; fn expecting(&self, output: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { output.write_str("an exact Decimal string") } fn visit_str(self, text: &str) -> Result { native_parse(text) .map(NativeDisplay) .ok_or_else(|| Error::custom("invalid Decimal")) } } decoder.deserialize_str(Visitor) } } fn json_encoded(values: &[DecimalInput]) -> Result, Fault> { Ok(values .iter() .map(|input| { if NATIVE { serde_json::to_string(&NativeDisplay(input.native)).unwrap() } else { serde_json::to_string(&input.value).unwrap() } }) .collect()) } fn json_decoded(values: &[String]) -> Result>, Fault> { Ok(values .iter() .map(|text| { if NATIVE { serde_json::from_str::(text) .ok() .map(|value| value.0.to_be_bytes()) } else { serde_json::from_str::(text) .ok() .map(Decimal::to_be_bytes) } }) .collect()) } fn wire_cases(inputs: &[DecimalInput]) { let texts = inputs .iter() .map(|input| serde_json::to_string(&input.text).unwrap()) .collect::>(); compare( "decimal_json_encode", inputs, 1000, json_encoded::, json_encoded::, |value| text_score(value), ); compare( "decimal_json_decode", &texts, 1000, json_decoded::, json_decoded::, |value| byte_score(value), ); let invalid = [ "1.25", "null", "[]", "\"NaN\"", "\"1e9999\"", "\" 1\"", "\"1\\u0000\"", "\"1\" true", ] .iter() .cycle() .take(112) .map(|value| (*value).to_owned()) .collect::>(); assert!( json_decoded::(&invalid) .unwrap() .iter() .all(Option::is_none) ); compare( "decimal_json_invalid", &invalid, 1000, json_decoded::, json_decoded::, |value| byte_score(value), ); }