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

mgrigorov pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/avro.git


The following commit(s) were added to refs/heads/main by this push:
     new 3c11f89c3 AVRO-3955: [Rust] allow deserializer to decode enum string 
(#2785)
3c11f89c3 is described below

commit 3c11f89c3cb8754f0ca977c06368c21c81ce19a8
Author: Florentin DUBOIS <florentin.dubois+git...@hey.com>
AuthorDate: Mon Mar 4 19:50:26 2024 +0100

    AVRO-3955: [Rust] allow deserializer to decode enum string (#2785)
    
    * See https://issues.apache.org/jira/browse/AVRO-3955
    
    Signed-off-by: Florentin Dubois <florentin.dub...@clever-cloud.com>
---
 lang/rust/avro/src/de.rs | 89 ++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 86 insertions(+), 3 deletions(-)

diff --git a/lang/rust/avro/src/de.rs b/lang/rust/avro/src/de.rs
index ceffadbd3..4d90d88e8 100644
--- a/lang/rust/avro/src/de.rs
+++ b/lang/rust/avro/src/de.rs
@@ -324,7 +324,7 @@ impl<'a, 'de> de::Deserializer<'de> for &'a 
Deserializer<'de> {
         V: Visitor<'de>,
     {
         match *self.input {
-            Value::String(ref s) => visitor.visit_borrowed_str(s),
+            Value::Enum(_, ref s) | Value::String(ref s) => 
visitor.visit_borrowed_str(s),
             Value::Bytes(ref bytes) | Value::Fixed(_, ref bytes) => {
                 String::from_utf8(bytes.to_owned())
                     .map_err(|e| de::Error::custom(e.to_string()))
@@ -344,7 +344,7 @@ impl<'a, 'de> de::Deserializer<'de> for &'a 
Deserializer<'de> {
                 ))),
             },
             _ => Err(de::Error::custom(format!(
-                "Expected a String|Bytes|Fixed|Uuid|Union, but got {:?}",
+                "Expected a String|Bytes|Fixed|Uuid|Union|Enum, but got {:?}",
                 self.input
             ))),
         }
@@ -665,7 +665,7 @@ pub fn from_value<'de, D: Deserialize<'de>>(value: &'de 
Value) -> Result<D, Erro
 mod tests {
     use num_bigint::BigInt;
     use pretty_assertions::assert_eq;
-    use serde::Serialize;
+    use serde::{Deserialize, Serialize};
     use serial_test::serial;
     use std::sync::atomic::Ordering;
     use uuid::Uuid;
@@ -676,6 +676,89 @@ mod tests {
 
     use super::*;
 
+    #[derive(PartialEq, Eq, Serialize, Deserialize, Debug)]
+    pub struct StringEnum {
+        pub source: String,
+    }
+
+    #[test]
+    fn avro_3955_decode_enum() -> TestResult {
+        let schema_content = r#"
+{
+  "name": "AccessLog",
+  "namespace": "com.clevercloud.accesslogs.common.avro",
+  "type": "record",
+  "fields": [
+    {
+      "name": "source",
+      "type": {
+        "type": "enum",
+        "name": "SourceType",
+        "items": "string",
+        "symbols": ["SOZU", "HAPROXY", "HAPROXY_TCP"]
+      }
+    }
+  ]
+}
+"#;
+
+        let schema = crate::Schema::parse_str(schema_content)?;
+        let data = StringEnum {
+            source: "SOZU".to_string(),
+        };
+
+        // encode into avro
+        let value = crate::to_value(&data)?;
+
+        let mut buf = std::io::Cursor::new(crate::to_avro_datum(&schema, 
value)?);
+
+        // decode from avro
+        let value = crate::from_avro_datum(&schema, &mut buf, None)?;
+
+        let decoded_data: StringEnum = crate::from_value(&value)?;
+
+        assert_eq!(decoded_data, data);
+
+        Ok(())
+    }
+
+    #[test]
+    fn avro_3955_encode_enum_data_with_wrong_content() -> TestResult {
+        let schema_content = r#"
+{
+  "name": "AccessLog",
+  "namespace": "com.clevercloud.accesslogs.common.avro",
+  "type": "record",
+  "fields": [
+    {
+      "name": "source",
+      "type": {
+        "type": "enum",
+        "name": "SourceType",
+        "items": "string",
+        "symbols": ["SOZU", "HAPROXY", "HAPROXY_TCP"]
+      }
+    }
+  ]
+}
+"#;
+
+        let schema = crate::Schema::parse_str(schema_content)?;
+        let data = StringEnum {
+            source: "WRONG_ITEM".to_string(),
+        };
+
+        // encode into avro
+        let value = crate::to_value(data)?;
+
+        // The following sentence have to fail has the data is wrong.
+        let encoded_data = crate::to_avro_datum(&schema, value);
+
+        assert!(encoded_data.is_err());
+
+        Ok(())
+    }
+
     #[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)]
     struct Test {
         a: i64,

Reply via email to