This is an automated email from the ASF dual-hosted git repository. mgrigorov pushed a commit to branch feat-add=support-for-serde-BigDecimal in repository https://gitbox.apache.org/repos/asf/avro-rs.git
commit b74c949b226e832276a7ec52cb28f26af31512e8 Author: Martin Tzvetanov Grigorov <[email protected]> AuthorDate: Fri Nov 8 16:02:22 2024 +0200 feat: Support (de)serializing BigDecimal values Signed-off-by: Martin Tzvetanov Grigorov <[email protected]> --- Cargo.lock | 57 +++++++++++++++++++++++++++++---------------------------- avro/Cargo.toml | 2 +- avro/src/de.rs | 14 ++++++++++++++ avro/src/ser.rs | 6 ++++++ 4 files changed, 50 insertions(+), 29 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a2223cd..8f7985f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -58,9 +58,9 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" [[package]] name = "anstyle" -version = "1.0.8" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" [[package]] name = "anyhow" @@ -174,6 +174,7 @@ dependencies = [ "num-integer", "num-traits", "serde", + "serde_json", ] [[package]] @@ -232,9 +233,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.1.28" +version = "1.1.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e80e3b6a3ab07840e1cae9b0666a63970dc28e8ed5ffbcdacbfc760c281bfc1" +checksum = "40545c26d092346d8a8dab71ee48e7685a7a9cba76e634790c215b41a4a7b4cf" dependencies = [ "jobserver", "libc", @@ -276,18 +277,18 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.19" +version = "4.5.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7be5744db7978a28d9df86a214130d106a89ce49644cbc4e3f0c22c3fba30615" +checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.5.19" +version = "4.5.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5fbc17d3ef8278f55b282b2a2e75ae6f6c7d4bb70ed3d0382375104bfafdb4b" +checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" dependencies = [ "anstyle", "clap_lex", @@ -444,9 +445,9 @@ dependencies = [ [[package]] name = "dary_heap" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7762d17f1241643615821a8455a0b2c3e803784b058693d990b11f2dce25a0ca" +checksum = "04d2cd9c18b9f454ed67da600630b021a8a80bf33f8c95896ab33aaf1c26b728" [[package]] name = "diff" @@ -718,9 +719,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.159" +version = "0.2.162" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" +checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398" [[package]] name = "libflate" @@ -748,9 +749,9 @@ dependencies = [ [[package]] name = "libm" -version = "0.2.8" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" +checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" [[package]] name = "lock_api" @@ -797,9 +798,9 @@ checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "minicov" -version = "0.3.5" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c71e683cd655513b99affab7d317deb690528255a0d5f717f1024093c12b169" +checksum = "f27fe9f1cc3c22e1687f9446c2083c4c5fc7f0bcf1c7a86bdbded14985895b4b" dependencies = [ "cc", "walkdir", @@ -896,9 +897,9 @@ checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] name = "pin-project-lite" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" +checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" [[package]] name = "pin-utils" @@ -1021,9 +1022,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", @@ -1110,9 +1111,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" +checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" [[package]] name = "ryu" @@ -1131,9 +1132,9 @@ dependencies = [ [[package]] name = "scc" -version = "2.2.0" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836f1e0f4963ef5288b539b643b35e043e76a32d0f4e47e67febf69576527f50" +checksum = "d8d25269dd3a12467afe2e510f69fb0b46b698e5afb296b59f2145259deaf8e8" dependencies = [ "sdd", ] @@ -1152,9 +1153,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "sdd" -version = "3.0.3" +version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60a7b59a5d9b0099720b417b6325d91a52cbf5b3dcb5041d864be53eefa58abc" +checksum = "49c1eeaf4b6a87c7479688c6d52b9f1153cedd3c489300564f932b065c6eab95" [[package]] name = "semver" @@ -1490,9 +1491,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.70" +version = "0.3.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0" +checksum = "f6488b90108c040df0fe62fa815cbdee25124641df01814dd7282749234c6112" dependencies = [ "js-sys", "wasm-bindgen", diff --git a/avro/Cargo.toml b/avro/Cargo.toml index 24caf14..c2682e0 100644 --- a/avro/Cargo.toml +++ b/avro/Cargo.toml @@ -54,7 +54,7 @@ name = "single" [dependencies] apache-avro-derive = { default-features = false, version = "0.18.0", path = "../avro_derive", optional = true } -bigdecimal = { default-features = false, version = "0.4.6", features = ["std", "serde"] } +bigdecimal = { default-features = false, version = "0.4.6", features = ["std", "serde-json"] } bzip2 = { default-features = false, version = "0.4.4", optional = true } crc32fast = { default-features = false, version = "1.4.2", optional = true } digest = { default-features = false, version = "0.10.7", features = ["core-api"] } diff --git a/avro/src/de.rs b/avro/src/de.rs index a932075..23329de 100644 --- a/avro/src/de.rs +++ b/avro/src/de.rs @@ -272,6 +272,7 @@ impl<'a, 'de> de::Deserializer<'de> for &'a Deserializer<'de> { Value::Map(ref items) => visitor.visit_map(MapDeserializer::new(items)), Value::Bytes(ref bytes) | Value::Fixed(_, ref bytes) => visitor.visit_bytes(bytes), Value::Decimal(ref d) => visitor.visit_bytes(&d.to_vec()?), + Value::BigDecimal(ref d) => visitor.visit_string(d.to_string()), Value::Enum(_, ref s) => visitor.visit_borrowed_str(s), _ => Err(de::Error::custom(format!( "unsupported union: {:?}", @@ -285,6 +286,7 @@ impl<'a, 'de> de::Deserializer<'de> for &'a Deserializer<'de> { Value::Map(ref items) => visitor.visit_map(MapDeserializer::new(items)), Value::Bytes(ref bytes) | Value::Fixed(_, ref bytes) => visitor.visit_bytes(bytes), Value::Decimal(ref d) => visitor.visit_bytes(&d.to_vec()?), + Value::BigDecimal(ref d) => visitor.visit_string(d.to_string()), Value::Enum(_, s) => visitor.visit_borrowed_str(s), value => Err(de::Error::custom(format!( "incorrect value of type: {:?}", @@ -367,6 +369,7 @@ impl<'a, 'de> de::Deserializer<'de> for &'a Deserializer<'de> { } Value::Uuid(ref u) => visitor.visit_bytes(u.as_bytes()), Value::Decimal(ref d) => visitor.visit_bytes(&d.to_vec()?), + Value::BigDecimal(ref d) => visitor.visit_string(d.to_string()), _ => Err(de::Error::custom(format!( "Expected a String|Bytes|Fixed|Uuid|Decimal, but got {:?}", self.input @@ -671,6 +674,7 @@ pub fn from_value<'de, D: Deserialize<'de>>(value: &'de Value) -> Result<D, Erro #[cfg(test)] mod tests { + use bigdecimal::BigDecimal; use num_bigint::BigInt; use pretty_assertions::assert_eq; use serde::{Deserialize, Serialize}; @@ -772,6 +776,7 @@ mod tests { a: i64, b: String, c: Decimal, + d: BigDecimal, } #[derive(Debug, Deserialize, Serialize, PartialEq, Eq)] @@ -866,11 +871,16 @@ mod tests { ("a".to_owned(), Value::Long(27)), ("b".to_owned(), Value::String("foo".to_owned())), ("c".to_owned(), Value::Decimal(Decimal::from(vec![1, 24]))), + ( + "d".to_owned(), + Value::BigDecimal(BigDecimal::new(BigInt::from(12), 2)), + ), ]); let expected = Test { a: 27, b: "foo".to_owned(), c: Decimal::from(vec![1, 24]), + d: BigDecimal::new(BigInt::from(12), 2), }; let final_value: Test = from_value(&test)?; assert_eq!(final_value, expected); @@ -882,6 +892,10 @@ mod tests { ("a".to_owned(), Value::Long(27)), ("b".to_owned(), Value::String("foo".to_owned())), ("c".to_owned(), Value::Decimal(Decimal::from(vec![1, 24]))), + ( + "d".to_owned(), + Value::BigDecimal(BigDecimal::new(BigInt::from(12), 2)), + ), ]), ), ("b".to_owned(), Value::Int(35)), diff --git a/avro/src/ser.rs b/avro/src/ser.rs index 32d496b..f835191 100644 --- a/avro/src/ser.rs +++ b/avro/src/ser.rs @@ -490,6 +490,8 @@ mod tests { use super::*; use crate::Decimal; use apache_avro_test_helper::TestResult; + use bigdecimal::BigDecimal; + use num_bigint::BigInt; use pretty_assertions::assert_eq; use serde::{Deserialize, Serialize}; use serial_test::serial; @@ -500,6 +502,7 @@ mod tests { a: i64, b: String, decimal: Decimal, + big_decimal: BigDecimal, } #[derive(Debug, Deserialize, Serialize)] @@ -691,11 +694,13 @@ mod tests { a: 27, b: "foo".to_owned(), decimal: Decimal::from(vec![1, 24]), + big_decimal: BigDecimal::new(BigInt::from(12), 2), }; let expected = Value::Record(vec![ ("a".to_owned(), Value::Long(27)), ("b".to_owned(), Value::String("foo".to_owned())), ("decimal".to_owned(), Value::Bytes(vec![1, 24])), + ("big_decimal".to_owned(), Value::String("0.12".into())), ]); assert_eq!(to_value(test.clone())?, expected); @@ -709,6 +714,7 @@ mod tests { ("a".to_owned(), Value::Long(27)), ("b".to_owned(), Value::String("foo".to_owned())), ("decimal".to_owned(), Value::Bytes(vec![1, 24])), + ("big_decimal".to_owned(), Value::String("0.12".into())), ]), ), ("b".to_owned(), Value::Int(35)),
