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

mgrigorov pushed a commit to branch avro-4024-nan-inf-float-defaults
in repository https://gitbox.apache.org/repos/asf/avro.git

commit 0af4e1b529c6b0b1ad7dd0a67383005d60ebed7e
Author: Martin Tzvetanov Grigorov <[email protected]>
AuthorDate: Mon Aug 5 21:53:45 2024 +0300

    AVRO-4024: [Rust] Improve the error messages when parsing unknown String 
into Value::Float/Double
    
    Signed-off-by: Martin Tzvetanov Grigorov <[email protected]>
---
 lang/rust/avro/src/error.rs |  4 ++--
 lang/rust/avro/src/types.rs | 48 ++++++++++++++++++++++++++++++++++++---------
 2 files changed, 41 insertions(+), 11 deletions(-)

diff --git a/lang/rust/avro/src/error.rs b/lang/rust/avro/src/error.rs
index 6e0de0dcb..c4ec2baa8 100644
--- a/lang/rust/avro/src/error.rs
+++ b/lang/rust/avro/src/error.rs
@@ -189,10 +189,10 @@ pub enum Error {
     GetLong(ValueKind),
 
     #[error("Double expected, got {0:?}")]
-    GetDouble(ValueKind),
+    GetDouble(Value),
 
     #[error("Float expected, got {0:?}")]
-    GetFloat(ValueKind),
+    GetFloat(Value),
 
     #[error("Bytes expected, got {0:?}")]
     GetBytes(ValueKind),
diff --git a/lang/rust/avro/src/types.rs b/lang/rust/avro/src/types.rs
index 0840c87ae..e9d4a31bd 100644
--- a/lang/rust/avro/src/types.rs
+++ b/lang/rust/avro/src/types.rs
@@ -908,11 +908,11 @@ impl Value {
             Value::Long(n) => Ok(Value::Float(n as f32)),
             Value::Float(x) => Ok(Value::Float(x)),
             Value::Double(x) => Ok(Value::Float(x as f32)),
-            Value::String(x) => match Self::parse_special_float(&x) {
+            Value::String(ref x) => match Self::parse_special_float(x) {
                 Some(f) => Ok(Value::Float(f)),
-                None => Err(Error::GetFloat(ValueKind::String)),
+                None => Err(Error::GetFloat(self)),
             },
-            other => Err(Error::GetFloat(other.into())),
+            other => Err(Error::GetFloat(other)),
         }
     }
 
@@ -922,18 +922,18 @@ impl Value {
             Value::Long(n) => Ok(Value::Double(n as f64)),
             Value::Float(x) => Ok(Value::Double(f64::from(x))),
             Value::Double(x) => Ok(Value::Double(x)),
-            Value::String(x) => match Self::parse_special_float(&x) {
-                Some(f) => Ok(Value::Double(f.into())),
-                None => Err(Error::GetDouble(ValueKind::String)),
+            Value::String(ref x) => match Self::parse_special_float(x) {
+                Some(f) => Ok(Value::Double(f64::from(f))),
+                None => Err(Error::GetDouble(self)),
             },
-            other => Err(Error::GetDouble(other.into())),
+            other => Err(Error::GetDouble(other)),
         }
     }
 
     /// IEEE 754 NaN and infinities are not valid JSON numbers.
     /// So they are represented in JSON as strings.
-    fn parse_special_float(s: &str) -> Option<f32> {
-        match s.trim().to_ascii_lowercase().as_str() {
+    fn parse_special_float(value: &str) -> Option<f32> {
+        match value.trim().to_ascii_lowercase().as_str() {
             "nan" | "+nan" | "-nan" => Some(f32::NAN),
             "inf" | "+inf" | "infinity" | "+infinity" => Some(f32::INFINITY),
             "-inf" | "-infinity" => Some(f32::NEG_INFINITY),
@@ -3138,4 +3138,34 @@ Field with name '"b"' is not a member of the map items"#,
             )
         );
     }
+
+    #[test]
+    fn avro_4024_resolve_double_from_unknown_string_err() -> TestResult {
+        let schema = Schema::parse_str(r#"{"type": "double"}"#)?;
+        let value = Value::String("blah".to_owned());
+        match value.resolve(&schema) {
+            Err(err @ Error::GetDouble(_)) => {
+                assert_eq!(format!("{err:?}"), r#"Double expected, got 
String("blah")"#);
+            }
+            other => {
+                panic!("Expected Error::GetDouble, got {other:?}");
+            }
+        }
+        Ok(())
+    }
+
+    #[test]
+    fn avro_4024_resolve_float_from_unknown_string_err() -> TestResult {
+        let schema = Schema::parse_str(r#"{"type": "float"}"#)?;
+        let value = Value::String("blah".to_owned());
+        match value.resolve(&schema) {
+            Err(err @ Error::GetFloat(_)) => {
+                assert_eq!(format!("{err:?}"), r#"Float expected, got 
String("blah")"#);
+            }
+            other => {
+                panic!("Expected Error::GetFloat, got {other:?}");
+            }
+        }
+        Ok(())
+    }
 }

Reply via email to