This is an automated email from the ASF dual-hosted git repository.
martin-g pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/avro-rs.git
The following commit(s) were added to refs/heads/main by this push:
new bf83d63 Deserializer support for BigDecimal when using
apache_avro::serde::bigdecimal (#543)
bf83d63 is described below
commit bf83d6379bd33641b0d1a463685527d73983cfa3
Author: jdarais <[email protected]>
AuthorDate: Fri May 15 15:05:52 2026 -0700
Deserializer support for BigDecimal when using
apache_avro::serde::bigdecimal (#543)
---
avro/src/serde/de.rs | 33 ++++++++++++++++++++++++++++++---
avro/src/serde/with.rs | 2 +-
2 files changed, 31 insertions(+), 4 deletions(-)
diff --git a/avro/src/serde/de.rs b/avro/src/serde/de.rs
index 82d40d5..d4a8792 100644
--- a/avro/src/serde/de.rs
+++ b/avro/src/serde/de.rs
@@ -16,7 +16,10 @@
// under the License.
//! Logic for serde-compatible deserialization.
-use crate::{Error, error::Details, serde::with::DE_BYTES_BORROWED,
types::Value};
+use crate::{
+ Error, bigdecimal::big_decimal_as_bytes, error::Details,
serde::with::DE_BYTES_BORROWED,
+ types::Value,
+};
use serde::{
Deserialize,
de::{self, DeserializeSeed, Deserializer as _, Visitor},
@@ -612,12 +615,13 @@ impl<'de> de::Deserializer<'de> for Deserializer<'de> {
}
Value::Uuid(u) => visitor.visit_bytes(u.as_bytes()),
Value::Decimal(d) => visitor.visit_bytes(&d.to_vec()?),
+ Value::BigDecimal(d) =>
visitor.visit_bytes(&big_decimal_as_bytes(d)?),
Value::Duration(d) => {
let d_bytes: [u8; 12] = d.into();
visitor.visit_bytes(&d_bytes[..])
}
_ => Err(de::Error::custom(format!(
- "Expected a String|Bytes|Fixed|Uuid|Decimal|Duration, but got
{:?}",
+ "Expected a
String|Bytes|Fixed|Uuid|BigDecimal|Decimal|Duration, but got {:?}",
self.input
))),
}
@@ -634,12 +638,13 @@ impl<'de> de::Deserializer<'de> for Deserializer<'de> {
}
Value::Uuid(u) => visitor.visit_byte_buf(Vec::from(u.as_bytes())),
Value::Decimal(d) => visitor.visit_byte_buf(d.to_vec()?),
+ Value::BigDecimal(d) =>
visitor.visit_byte_buf(big_decimal_as_bytes(d)?),
Value::Duration(d) => {
let d_bytes: [u8; 12] = d.into();
visitor.visit_byte_buf(Vec::from(d_bytes))
}
_ => Err(de::Error::custom(format!(
- "Expected a String|Bytes|Fixed|Uuid|Decimal|Duration, but got
{:?}",
+ "Expected a
String|Bytes|Fixed|Uuid|BigDecimal|Decimal|Duration, but got {:?}",
self.input
))),
}
@@ -1799,6 +1804,28 @@ mod tests {
Ok(())
}
+ #[test]
+ fn avro_543_deserialize_bigdecimal_as_bytes() -> TestResult {
+ #[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)]
+ #[serde(transparent)]
+ struct WrappedBigDecimal(
+ // crate::serde::bigdecimal serializes/deserializes BigDecimal as
bytes
+ #[serde(with = "crate::serde::bigdecimal")] bigdecimal::BigDecimal,
+ );
+
+ let expected_decimal = WrappedBigDecimal(str::parse("7.45")?);
+ let value = Value::BigDecimal(str::parse("7.45")?);
+ let actual_decimal = from_value::<WrappedBigDecimal>(&value)?;
+
+ assert_eq!(actual_decimal, expected_decimal.clone());
+
+ let value = Value::Union(0,
Box::new(Value::BigDecimal(str::parse("7.45")?)));
+ let raw_bytes = from_value::<Option<WrappedBigDecimal>>(&value)?;
+ assert_eq!(raw_bytes, Some(expected_decimal));
+
+ Ok(())
+ }
+
#[test]
fn test_avro_3892_deserialize_bytes_from_uuid() -> TestResult {
let uuid_str = "10101010-2020-2020-2020-101010101010";
diff --git a/avro/src/serde/with.rs b/avro/src/serde/with.rs
index 6778916..13f199f 100644
--- a/avro/src/serde/with.rs
+++ b/avro/src/serde/with.rs
@@ -510,7 +510,7 @@ pub mod slice_opt {
///
/// When used with different serialization formats, this will write bytes.
///
-/// See usage with below example:
+/// Example usage:
/// ```
/// # use apache_avro::{AvroSchema, BigDecimal};
/// # use serde::{Deserialize, Serialize};