Skip to content

Commit

Permalink
AVRO-3886: [Rust] Serialize attribute in schema to support custom lo…
Browse files Browse the repository at this point in the history
…gical type (#2557)

* AVRO-3886: serialize attribute in schema to support custom logical type

* AVRO-3886: [Rust] Use all kinds of JSON values for the attributes to serialize

Signed-off-by: Martin Tzvetanov Grigorov <[email protected]>

---------

Signed-off-by: Martin Tzvetanov Grigorov <[email protected]>
Co-authored-by: ZENOTME <[email protected]>
Co-authored-by: Martin Tzvetanov Grigorov <[email protected]>
  • Loading branch information
3 people authored Oct 18, 2023
1 parent 9f5872f commit d6837ed
Showing 1 changed file with 77 additions and 7 deletions.
84 changes: 77 additions & 7 deletions lang/rust/avro/src/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1620,9 +1620,8 @@ impl Parser {
}
}

let name = Name::parse(complex, enclosing_namespace)?;
let fully_qualified_name = name.clone();
let aliases = fix_aliases_namespace(complex.aliases(), &name.namespace);
let fully_qualified_name = Name::parse(complex, enclosing_namespace)?;
let aliases = fix_aliases_namespace(complex.aliases(), &fully_qualified_name.namespace);

let symbols: Vec<String> = symbols_opt
.and_then(|v| v.as_array())
Expand Down Expand Up @@ -1753,9 +1752,8 @@ impl Parser {
None => Err(Error::GetFixedSizeField),
}?;

let name = Name::parse(complex, enclosing_namespace)?;
let fully_qualified_name = name.clone();
let aliases = fix_aliases_namespace(complex.aliases(), &name.namespace);
let fully_qualified_name = Name::parse(complex, enclosing_namespace)?;
let aliases = fix_aliases_namespace(complex.aliases(), &fully_qualified_name.namespace);

let schema = Schema::Fixed(FixedSchema {
name: fully_qualified_name.clone(),
Expand Down Expand Up @@ -1845,6 +1843,7 @@ impl Serialize for Schema {
ref aliases,
ref doc,
ref fields,
ref attributes,
..
}) => {
let mut map = serializer.serialize_map(None)?;
Expand All @@ -1860,12 +1859,16 @@ impl Serialize for Schema {
map.serialize_entry("aliases", aliases)?;
}
map.serialize_entry("fields", fields)?;
for attr in attributes {
map.serialize_entry(attr.0, attr.1)?;
}
map.end()
}
Schema::Enum(EnumSchema {
ref name,
ref symbols,
ref aliases,
ref attributes,
..
}) => {
let mut map = serializer.serialize_map(None)?;
Expand All @@ -1879,14 +1882,17 @@ impl Serialize for Schema {
if let Some(ref aliases) = aliases {
map.serialize_entry("aliases", aliases)?;
}
for attr in attributes {
map.serialize_entry(attr.0, attr.1)?;
}
map.end()
}
Schema::Fixed(FixedSchema {
ref name,
ref doc,
ref size,
ref aliases,
..
ref attributes,
}) => {
let mut map = serializer.serialize_map(None)?;
map.serialize_entry("type", "fixed")?;
Expand All @@ -1902,6 +1908,10 @@ impl Serialize for Schema {
if let Some(ref aliases) = aliases {
map.serialize_entry("aliases", aliases)?;
}

for attr in attributes {
map.serialize_entry(attr.0, attr.1)?;
}
map.end()
}
Schema::Decimal(DecimalSchema {
Expand Down Expand Up @@ -6125,4 +6135,64 @@ mod tests {

Ok(())
}

#[test]
fn avro_3886_serialize_attributes() -> TestResult {
let attributes = BTreeMap::from([
("string_key".into(), "value".into()),
("number_key".into(), 1.23.into()),
("null_key".into(), Value::Null),
(
"array_key".into(),
Value::Array(vec![1.into(), 2.into(), 3.into()]),
),
("object_key".into(), Value::Object(Map::default())),
]);

// Test serialize enum attributes
let schema = Schema::Enum(EnumSchema {
name: Name::new("a")?,
aliases: None,
doc: None,
symbols: vec![],
default: None,
attributes: attributes.clone(),
});
let serialized = serde_json::to_string(&schema)?;
assert_eq!(
r#"{"type":"enum","name":"a","symbols":[],"array_key":[1,2,3],"null_key":null,"number_key":1.23,"object_key":{},"string_key":"value"}"#,
&serialized
);

// Test serialize fixed custom_attributes
let schema = Schema::Fixed(FixedSchema {
name: Name::new("a")?,
aliases: None,
doc: None,
size: 1,
attributes: attributes.clone(),
});
let serialized = serde_json::to_string(&schema)?;
assert_eq!(
r#"{"type":"fixed","name":"a","size":1,"array_key":[1,2,3],"null_key":null,"number_key":1.23,"object_key":{},"string_key":"value"}"#,
&serialized
);

// Test serialize record custom_attributes
let schema = Schema::Record(RecordSchema {
name: Name::new("a")?,
aliases: None,
doc: None,
fields: vec![],
lookup: BTreeMap::new(),
attributes,
});
let serialized = serde_json::to_string(&schema)?;
assert_eq!(
r#"{"type":"record","name":"a","fields":[],"array_key":[1,2,3],"null_key":null,"number_key":1.23,"object_key":{},"string_key":"value"}"#,
&serialized
);

Ok(())
}
}

0 comments on commit d6837ed

Please sign in to comment.