From 2b88f1eed00b800814bc3f14aacb02a220b22738 Mon Sep 17 00:00:00 2001 From: Jonathan Turner Date: Sun, 15 Sep 2019 05:48:24 +1200 Subject: [PATCH] Serialize bigint/bigdecimal as i64/f64 --- src/cli.rs | 1 + src/data/base.rs | 54 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/src/cli.rs b/src/cli.rs index 7b6f6e863e..e7ab3ec2e3 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -59,6 +59,7 @@ fn load_plugin(path: &std::path::Path, context: &mut Context) -> Result<(), Shel let result = match reader.read_line(&mut input) { Ok(count) => { trace!("processing response ({} bytes)", count); + trace!("response: {}", input); let response = serde_json::from_str::>>(&input); match response { diff --git a/src/data/base.rs b/src/data/base.rs index c80cf409f0..1922ee3fc5 100644 --- a/src/data/base.rs +++ b/src/data/base.rs @@ -13,10 +13,64 @@ use std::fmt; use std::path::PathBuf; use std::time::SystemTime; +mod serde_bigint { + use num_traits::cast::FromPrimitive; + use num_traits::cast::ToPrimitive; + + pub fn serialize(big_int: &super::BigInt, serializer: S) -> Result + where + S: serde::Serializer, + { + serde::Serialize::serialize( + &big_int + .to_i64() + .ok_or(serde::ser::Error::custom("expected a i64-sized bignum"))?, + serializer, + ) + } + + pub fn deserialize<'de, D>(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + let x: i64 = serde::Deserialize::deserialize(deserializer)?; + Ok(super::BigInt::from_i64(x) + .ok_or(serde::de::Error::custom("expected a i64-sized bignum"))?) + } +} + +mod serde_bigdecimal { + use num_traits::cast::FromPrimitive; + use num_traits::cast::ToPrimitive; + + pub fn serialize(big_decimal: &super::BigDecimal, serializer: S) -> Result + where + S: serde::Serializer, + { + serde::Serialize::serialize( + &big_decimal + .to_f64() + .ok_or(serde::ser::Error::custom("expected a f64-sized bignum"))?, + serializer, + ) + } + + pub fn deserialize<'de, D>(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + let x: f64 = serde::Deserialize::deserialize(deserializer)?; + Ok(super::BigDecimal::from_f64(x) + .ok_or(serde::de::Error::custom("expected a f64-sized bigdecimal"))?) + } +} + #[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, Deserialize, Serialize)] pub enum Primitive { Nothing, + #[serde(with = "serde_bigint")] Int(BigInt), + #[serde(with = "serde_bigdecimal")] Decimal(BigDecimal), Bytes(u64), String(String),