You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@avro.apache.org by mg...@apache.org on 2024/01/11 08:43:57 UTC

(avro) 01/01: AVRO-3928: [Rust] Convert serde_json::Value::Number to apache_avro::types::Value::Int when possible

This is an automated email from the ASF dual-hosted git repository.

mgrigorov pushed a commit to branch avro-3928-fix-parsing-defaults-for-logical-int
in repository https://gitbox.apache.org/repos/asf/avro.git

commit 00f6ef1178645d851a34214af54ef0f814ec3a7e
Author: Martin Tzvetanov Grigorov <mg...@apache.org>
AuthorDate: Thu Jan 11 10:41:32 2024 +0200

    AVRO-3928: [Rust] Convert serde_json::Value::Number to apache_avro::types::Value::Int when possible
    
    If the number is bigger than i32::MIN and smaller than i32::MAX then
    convert to types::Value::Int, otherwise to types::Value::Long
    
    Signed-off-by: Martin Tzvetanov Grigorov <mg...@apache.org>
---
 lang/rust/avro/src/schema.rs | 30 ++++++++++++++++++++++++++++++
 lang/rust/avro/src/types.rs  |  9 ++++++++-
 2 files changed, 38 insertions(+), 1 deletion(-)

diff --git a/lang/rust/avro/src/schema.rs b/lang/rust/avro/src/schema.rs
index 680a54a02..a7c622335 100644
--- a/lang/rust/avro/src/schema.rs
+++ b/lang/rust/avro/src/schema.rs
@@ -6611,4 +6611,34 @@ mod tests {
 
         Ok(())
     }
+
+    #[test]
+    fn avro_3928_parse_int_based_schema_with_default() -> TestResult {
+        let schema = r#"
+        {
+          "type": "record",
+          "name": "DateLogicalType",
+          "fields": [ {
+            "name": "birthday",
+            "type": {"type": "int", "logicalType": "date"},
+            "default": 1681601653
+          } ]
+        }"#;
+
+        match Schema::parse_str(schema)? {
+            Schema::Record(record_schema) => {
+                assert_eq!(record_schema.fields.len(), 1);
+                let field = record_schema.fields.first().unwrap();
+                assert_eq!(field.name, "birthday");
+                assert_eq!(field.schema, Schema::Date);
+                assert_eq!(
+                    types::Value::from(field.default.clone().unwrap()),
+                    types::Value::Int(1681601653)
+                );
+            }
+            _ => unreachable!("Expected Schema::Record"),
+        }
+
+        Ok(())
+    }
 }
diff --git a/lang/rust/avro/src/types.rs b/lang/rust/avro/src/types.rs
index 62752bbba..b9ce76529 100644
--- a/lang/rust/avro/src/types.rs
+++ b/lang/rust/avro/src/types.rs
@@ -281,7 +281,14 @@ impl From<JsonValue> for Value {
         match value {
             JsonValue::Null => Self::Null,
             JsonValue::Bool(b) => b.into(),
-            JsonValue::Number(ref n) if n.is_i64() => Value::Long(n.as_i64().unwrap()),
+            JsonValue::Number(ref n) if n.is_i64() => {
+                let n = n.as_i64().unwrap();
+                if n >= i32::MIN as i64 && n <= i32::MAX as i64 {
+                    Value::Int(n as i32)
+                } else {
+                    Value::Long(n)
+                }
+            }
             JsonValue::Number(ref n) if n.is_f64() => Value::Double(n.as_f64().unwrap()),
             JsonValue::Number(n) => Value::Long(n.as_u64().unwrap() as i64), // TODO: Not so great
             JsonValue::String(s) => s.into(),