Skip to content

Commit

Permalink
AVRO-3764: [Rust]: Add resolve method with schemata for an automatic …
Browse files Browse the repository at this point in the history
…Schema::Ref resolving (apache#2262)

* feat: add draft method to resolve with schemata

* feat: add test for resolving with schemata

* AVRO-3764: Minor improvements in the test

Signed-off-by: Martin Tzvetanov Grigorov <mgrigorov@apache.org>

---------

Signed-off-by: Martin Tzvetanov Grigorov <mgrigorov@apache.org>
Co-authored-by: Fedor Telnov <f.telnov@picodata.io>
Co-authored-by: Martin Tzvetanov Grigorov <mgrigorov@apache.org>
  • Loading branch information
3 people committed May 31, 2023
1 parent d1b5f9a commit cdfd66f
Showing 1 changed file with 52 additions and 0 deletions.
52 changes: 52 additions & 0 deletions lang/rust/avro/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,18 @@ impl Value {
self.resolve_internal(schema, rs.get_names(), &enclosing_namespace)
}

/// Attempt to perform schema resolution on the value, with the given
/// [Schema](../schema/enum.Schema.html) and set of schemas to use for Refs resolution.
///
/// See [Schema Resolution](https://avro.apache.org/docs/current/spec.html#Schema+Resolution)
/// in the Avro specification for the full set of rules of schema
/// resolution.
pub fn resolve_schemata(self, schema: &Schema, schemata: Vec<&Schema>) -> AvroResult<Self> {
let enclosing_namespace = schema.namespace();
let rs = ResolvedSchema::try_from(schemata)?;
self.resolve_internal(schema, rs.get_names(), &enclosing_namespace)
}

fn resolve_internal(
mut self,
schema: &Schema,
Expand Down Expand Up @@ -2638,4 +2650,44 @@ Field with name '"b"' is not a member of the map items"#,
fn test_avro_3688_field_b_set() {
avro_3688_schema_resolution_panic(true);
}

#[test]
fn test_avro_3764_use_resolve_schemata() {
let referenced_schema =
r#"{"name": "enumForReference", "type": "enum", "symbols": ["A", "B"]}"#;
let main_schema = r#"{"name": "recordWithReference", "type": "record", "fields": [{"name": "reference", "type": "enumForReference"}]}"#;

let value: serde_json::Value = serde_json::from_str(
r#"
{
"reference": "A"
}
"#,
)
.unwrap();

let avro_value = Value::from(value);

let schemas = Schema::parse_list(&[main_schema, referenced_schema]).unwrap();

let main_schema = schemas.get(0).unwrap();
let schemata: Vec<_> = schemas.iter().skip(1).collect();

let resolve_result = avro_value
.clone()
.resolve_schemata(main_schema, schemata.clone());

assert!(
resolve_result.is_ok(),
"result of resolving with schemata should be ok, got: {:?}",
resolve_result
);

let resolve_result = avro_value.resolve(main_schema);
assert!(
resolve_result.is_err(),
"result of resolving without schemata should be err, got: {:?}",
resolve_result
);
}
}

0 comments on commit cdfd66f

Please sign in to comment.