This is an automated email from the ASF dual-hosted git repository. mgrigorov pushed a commit to branch branch-1.11 in repository https://gitbox.apache.org/repos/asf/avro.git
commit 66f2b47edc2b550616f007fc6e41d5f66771f569 Author: Martin Grigorov <[email protected]> AuthorDate: Mon Jan 10 14:02:30 2022 +0200 AVRO-3214 Rust: Support 'doc' attribute for FixedSchema (#1343) (cherry picked from commit 0811b827a233c415a5b48612817148b01db102ac) --- lang/rust/src/decode.rs | 2 ++ lang/rust/src/schema.rs | 39 +++++++++++++++++++++++++++++++++-- lang/rust/src/schema_compatibility.rs | 2 ++ lang/rust/src/types.rs | 4 +++- lang/rust/src/writer.rs | 2 ++ lang/rust/tests/schema.rs | 8 ++++++- 6 files changed, 53 insertions(+), 4 deletions(-) diff --git a/lang/rust/src/decode.rs b/lang/rust/src/decode.rs index 0714dcd..5639d28 100644 --- a/lang/rust/src/decode.rs +++ b/lang/rust/src/decode.rs @@ -298,6 +298,7 @@ mod tests { use num_bigint::ToBigInt; let inner = Box::new(Schema::Fixed { size: 2, + doc: None, name: Name::new("decimal"), }); let schema = Schema::Decimal { @@ -323,6 +324,7 @@ mod tests { let inner = Box::new(Schema::Fixed { size: 13, name: Name::new("decimal"), + doc: None, }); let schema = Schema::Decimal { inner, diff --git a/lang/rust/src/schema.rs b/lang/rust/src/schema.rs index da8c0c3..3617bb1 100644 --- a/lang/rust/src/schema.rs +++ b/lang/rust/src/schema.rs @@ -109,7 +109,11 @@ pub enum Schema { symbols: Vec<String>, }, /// A `fixed` Avro schema. - Fixed { name: Name, size: usize }, + Fixed { + name: Name, + doc: Documentation, + size: usize, + }, /// Logical type which represents `Decimal` values. The underlying type is serialized and /// deserialized as `Schema::Bytes` or `Schema::Fixed`. /// @@ -871,6 +875,11 @@ impl Parser { fn parse_fixed(complex: &Map<String, Value>) -> AvroResult<Schema> { let name = Name::parse(complex)?; + let doc = complex.get("doc").and_then(|v| match &v { + Value::String(ref docstr) => Some(docstr.clone()), + _ => None, + }); + let size = complex .get("size") .and_then(|v| v.as_i64()) @@ -878,6 +887,7 @@ impl Parser { Ok(Schema::Fixed { name, + doc, size: size as usize, }) } @@ -949,10 +959,17 @@ impl Serialize for Schema { map.serialize_entry("symbols", symbols)?; map.end() } - Schema::Fixed { ref name, ref size } => { + Schema::Fixed { + ref name, + ref doc, + ref size, + } => { let mut map = serializer.serialize_map(None)?; map.serialize_entry("type", "fixed")?; map.serialize_entry("name", &name.name)?; + if let Some(ref docstr) = doc { + map.serialize_entry("doc", docstr)?; + } map.serialize_entry("size", size)?; map.end() } @@ -1011,6 +1028,7 @@ impl Serialize for Schema { // duration should be or typically is. let inner = Schema::Fixed { name: Name::new("duration"), + doc: None, size: 12, }; map.serialize_entry("type", &inner)?; @@ -1311,6 +1329,23 @@ mod tests { let expected = Schema::Fixed { name: Name::new("test"), + doc: None, + size: 16usize, + }; + + assert_eq!(expected, schema); + } + + #[test] + fn test_fixed_schema_with_documentation() { + let schema = Schema::parse_str( + r#"{"type": "fixed", "name": "test", "size": 16, "doc": "FixedSchema documentation"}"#, + ) + .unwrap(); + + let expected = Schema::Fixed { + name: Name::new("test"), + doc: Some(String::from("FixedSchema documentation")), size: 16usize, }; diff --git a/lang/rust/src/schema_compatibility.rs b/lang/rust/src/schema_compatibility.rs index 7f2a5cf..5ba46e1 100644 --- a/lang/rust/src/schema_compatibility.rs +++ b/lang/rust/src/schema_compatibility.rs @@ -232,11 +232,13 @@ impl SchemaCompatibility { SchemaKind::Fixed => { if let Schema::Fixed { name: w_name, + doc: _w_doc, size: w_size, } = writers_schema { if let Schema::Fixed { name: r_name, + doc: _r_doc, size: r_size, } = readers_schema { diff --git a/lang/rust/src/types.rs b/lang/rust/src/types.rs index 63876da..75f0509 100644 --- a/lang/rust/src/types.rs +++ b/lang/rust/src/types.rs @@ -840,6 +840,7 @@ mod tests { let schema = Schema::Fixed { size: 4, name: Name::new("some_fixed"), + doc: None, }; assert!(Value::Fixed(4, vec![0, 0, 0, 0]).validate(&schema)); @@ -1038,7 +1039,8 @@ mod tests { scale: 1, inner: Box::new(Schema::Fixed { name: Name::new("decimal"), - size: 20 + size: 20, + doc: None }) }) .is_ok()); diff --git a/lang/rust/src/writer.rs b/lang/rust/src/writer.rs index efdd992..41e77c9 100644 --- a/lang/rust/src/writer.rs +++ b/lang/rust/src/writer.rs @@ -503,6 +503,7 @@ mod tests { let size = 30; let inner = Schema::Fixed { name: Name::new("decimal"), + doc: None, size, }; let value = vec![0u8; size]; @@ -540,6 +541,7 @@ mod tests { fn duration() -> TestResult<()> { let inner = Schema::Fixed { name: Name::new("duration"), + doc: None, size: 12, }; let value = Value::Duration(Duration::new( diff --git a/lang/rust/tests/schema.rs b/lang/rust/tests/schema.rs index d9fdefc..cc96429 100644 --- a/lang/rust/tests/schema.rs +++ b/lang/rust/tests/schema.rs @@ -336,6 +336,10 @@ const DOC_EXAMPLES: &[(&str, bool)] = &[ r#"{"type": "enum", "name": "Test", "symbols": ["A", "B"], "doc": "Doc String"}"#, true, ), + ( + r#"{"type": "fixed", "name": "Test", "size": 1, "doc": "Fixed Doc String"}"#, + true, + ), ]; const OTHER_ATTRIBUTES_EXAMPLES: &[(&str, bool)] = &[ @@ -1229,7 +1233,9 @@ fn test_doc_attributes() { match schema { Schema::Enum { doc, .. } => assert!(doc.is_some()), Schema::Record { doc, .. } => assert!(doc.is_some()), - _ => (), + Schema::Fixed { doc, .. } => assert!(doc.is_some()), + Schema::String => (), + _ => unreachable!("Unexpected schema type: {:?}", schema), } }
