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,