PookieBuns commented on code in PR #458:
URL: https://github.com/apache/avro-rs/pull/458#discussion_r2788766740
##########
avro/tests/nullable_union.rs:
##########
@@ -0,0 +1,982 @@
+use apache_avro::{AvroResult, Reader, Schema, Writer, from_value,
types::Value};
+use serde::de::DeserializeOwned;
+use serde::{Deserialize, Serialize};
+
+struct TestCase<'a, T> {
+ input: T,
+ schema: &'a Schema,
+ expected_avro: &'a Value,
+}
+
+fn test_serialize<T>(test_case: TestCase<T>) -> AvroResult<()>
+where
+ T: Serialize + std::fmt::Debug,
+{
+ let mut writer = Writer::new(test_case.schema, Vec::new())?;
+ writer.append_ser(&test_case.input)?;
+ let bytes = writer.into_inner()?;
+ let mut reader = Reader::with_schema(test_case.schema, &bytes[..])?;
+ let read_avro_value = reader.next().unwrap()?;
+ assert_eq!(
+ &read_avro_value, test_case.expected_avro,
+ "serialization is not correct: expected: {:?}, got: {:?}, input: {:?}",
+ test_case.expected_avro, read_avro_value, test_case.input
+ );
+ Ok(())
+}
+
+fn test_deserialize<T>(test_case: TestCase<T>) -> AvroResult<()>
+where
+ T: DeserializeOwned + std::fmt::Debug + std::cmp::PartialEq,
+{
+ let deserialized: T = from_value(test_case.expected_avro)?;
+ assert_eq!(
+ deserialized, test_case.input,
+ "deserialization is not correct: expected: {:?}, got: {:?}",
+ test_case.input, deserialized,
+ );
+ Ok(())
+}
+
+mod nullable_enum {
+ use super::*;
+
+ const NULLABLE_ENUM_SCHEMA: &str = r#"
+ {
+ "name": "MyUnion",
+ "type": [
+ "null",
+ {
+ "type": "enum",
+ "name": "MyEnum",
+ "symbols": ["A", "B"]
+ }
+ ]
+ }
+ "#;
+
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ enum MyEnum {
+ A,
+ B,
+ }
+
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ enum MyUnionNullable {
+ Null,
+ MyEnum(MyEnum),
+ }
+
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ enum MyUnionAvroJsonEncoding {
+ MyEnum(MyEnum),
+ }
+
+ fn schema() -> Schema {
+ Schema::parse_str(NULLABLE_ENUM_SCHEMA).unwrap()
+ }
+
+ fn null_variant_expected_avro() -> Value {
+ Value::Union(0, Box::new(Value::Null))
+ }
+
+ fn a_variant_expected_avro() -> Value {
+ Value::Union(1, Box::new(Value::Enum(0, "A".to_string())))
+ }
+
+ #[test]
+ fn serialize_null_variant_enum_null() -> AvroResult<()> {
+ test_serialize(TestCase {
+ input: MyUnionNullable::Null,
+ schema: &schema(),
+ expected_avro: &null_variant_expected_avro(),
+ })
+ }
+
+ #[test]
+ fn deserialize_null_variant_enum_null() -> AvroResult<()> {
+ test_deserialize(TestCase {
+ input: MyUnionNullable::Null,
+ schema: &schema(),
+ expected_avro: &null_variant_expected_avro(),
+ })
+ }
+
+ #[test]
+ fn serialize_rusty_null() -> AvroResult<()> {
+ test_serialize(TestCase {
+ input: None::<MyEnum>,
+ schema: &schema(),
+ expected_avro: &null_variant_expected_avro(),
+ })
+ }
+
+ #[test]
+ fn deserialize_rusty_null() -> AvroResult<()> {
+ test_deserialize(TestCase {
+ input: None::<MyEnum>,
+ schema: &schema(),
+ expected_avro: &null_variant_expected_avro(),
+ })
+ }
+
+ #[test]
+ fn serialize_avro_json_encoding_compatible_null() -> AvroResult<()> {
+ test_serialize(TestCase {
+ input: None::<MyUnionAvroJsonEncoding>,
+ schema: &schema(),
+ expected_avro: &null_variant_expected_avro(),
+ })
+ }
+
+ #[test]
+ fn deserialize_avro_json_encoding_compatible_null() -> AvroResult<()> {
+ test_deserialize(TestCase {
+ input: None::<MyUnionAvroJsonEncoding>,
+ schema: &schema(),
+ expected_avro: &null_variant_expected_avro(),
+ })
+ }
+
+ #[test]
+ fn serialize_null_variant_enum_my_enum_a() -> AvroResult<()> {
+ test_serialize(TestCase {
+ input: MyUnionNullable::MyEnum(MyEnum::A),
+ schema: &schema(),
+ expected_avro: &a_variant_expected_avro(),
+ })
+ }
+
+ #[test]
+ fn deserialize_null_variant_enum_my_enum_a() -> AvroResult<()> {
+ test_deserialize(TestCase {
+ input: MyUnionNullable::MyEnum(MyEnum::A),
+ schema: &schema(),
+ expected_avro: &a_variant_expected_avro(),
+ })
+ }
+
+ #[test]
+ fn serialize_rusty_my_enum_a() -> AvroResult<()> {
+ test_serialize(TestCase {
+ input: Some(MyEnum::A),
+ schema: &schema(),
+ expected_avro: &a_variant_expected_avro(),
+ })
+ }
+
+ #[test]
+ fn deserialize_rusty_my_enum_a() -> AvroResult<()> {
+ test_deserialize(TestCase {
+ input: Some(MyEnum::A),
+ schema: &schema(),
+ expected_avro: &a_variant_expected_avro(),
+ })
+ }
+
+ #[test]
+ fn serialize_avro_json_encoding_compatible_my_enum_a() -> AvroResult<()> {
+ test_serialize(TestCase {
+ input: Some(MyUnionAvroJsonEncoding::MyEnum(MyEnum::A)),
+ schema: &schema(),
+ expected_avro: &a_variant_expected_avro(),
+ })
+ }
+
+ #[test]
+ fn deserialize_avro_json_encoding_compatible_my_enum_a() -> AvroResult<()>
{
+ test_deserialize(TestCase {
+ input: Some(MyUnionAvroJsonEncoding::MyEnum(MyEnum::A)),
+ schema: &schema(),
+ expected_avro: &a_variant_expected_avro(),
+ })
+ }
+}
+
+mod nullable_primitive_int {
+ use super::*;
+
+ const NULLABLE_INT_SCHEMA: &str = r#"
+ {
+ "name": "MyUnion",
+ "type": [
+ "null",
+ "int"
+ ]
+ }
+ "#;
+
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ enum MyUnionNullable {
+ Null,
+ Int(i32),
+ }
+
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ enum MyUnionAvroJsonEncoding {
+ #[serde(rename = "int")]
+ Int(i32),
+ }
+
+ fn schema() -> Schema {
+ Schema::parse_str(NULLABLE_INT_SCHEMA).unwrap()
+ }
+
+ fn null_variant_expected_avro() -> Value {
+ Value::Union(0, Box::new(Value::Null))
+ }
+
+ fn int_variant_expected_avro(v: i32) -> Value {
+ Value::Union(1, Box::new(Value::Int(v)))
+ }
+
+ #[test]
+ fn serialize_null_variant_enum_null() -> AvroResult<()> {
+ test_serialize(TestCase {
+ input: MyUnionNullable::Null,
+ schema: &schema(),
+ expected_avro: &null_variant_expected_avro(),
+ })
+ }
+
+ #[test]
+ fn deserialize_null_variant_enum_null() -> AvroResult<()> {
+ test_deserialize(TestCase {
+ input: MyUnionNullable::Null,
+ schema: &schema(),
+ expected_avro: &null_variant_expected_avro(),
+ })
+ }
+
+ #[test]
+ fn serialize_rusty_null() -> AvroResult<()> {
+ test_serialize(TestCase {
+ input: None::<i32>,
+ schema: &schema(),
+ expected_avro: &null_variant_expected_avro(),
+ })
+ }
+
+ #[test]
+ fn deserialize_rusty_null() -> AvroResult<()> {
+ test_deserialize(TestCase {
+ input: None::<i32>,
+ schema: &schema(),
+ expected_avro: &null_variant_expected_avro(),
+ })
+ }
+
+ #[test]
+ fn serialize_avro_json_encoding_compatible_null() -> AvroResult<()> {
+ test_serialize(TestCase {
+ input: None::<MyUnionAvroJsonEncoding>,
+ schema: &schema(),
+ expected_avro: &null_variant_expected_avro(),
+ })
+ }
+
+ #[test]
+ fn deserialize_avro_json_encoding_compatible_null() -> AvroResult<()> {
+ test_deserialize(TestCase {
+ input: None::<MyUnionAvroJsonEncoding>,
+ schema: &schema(),
+ expected_avro: &null_variant_expected_avro(),
+ })
+ }
+
+ #[test]
+ fn serialize_null_variant_enum_int_42() -> AvroResult<()> {
+ test_serialize(TestCase {
+ input: MyUnionNullable::Int(42),
+ schema: &schema(),
+ expected_avro: &int_variant_expected_avro(42),
+ })
+ }
+
+ #[test]
+ fn deserialize_null_variant_enum_int_42() -> AvroResult<()> {
+ test_deserialize(TestCase {
+ input: MyUnionNullable::Int(42),
+ schema: &schema(),
+ expected_avro: &int_variant_expected_avro(42),
+ })
+ }
+
+ #[test]
+ fn serialize_rusty_int_42() -> AvroResult<()> {
+ test_serialize(TestCase {
+ input: Some(42_i32),
+ schema: &schema(),
+ expected_avro: &int_variant_expected_avro(42),
+ })
+ }
+
+ #[test]
+ fn deserialize_rusty_int_42() -> AvroResult<()> {
+ test_deserialize(TestCase {
+ input: Some(42_i32),
+ schema: &schema(),
+ expected_avro: &int_variant_expected_avro(42),
+ })
+ }
+
+ #[test]
+ fn serialize_avro_json_encoding_compatible_int_42() -> AvroResult<()> {
+ test_serialize(TestCase {
+ input: Some(MyUnionAvroJsonEncoding::Int(42)),
+ schema: &schema(),
+ expected_avro: &int_variant_expected_avro(42),
+ })
+ }
+
+ #[test]
+ fn deserialize_avro_json_encoding_compatible_int_42() -> AvroResult<()> {
+ test_deserialize(TestCase {
+ input: Some(MyUnionAvroJsonEncoding::Int(42)),
+ schema: &schema(),
+ expected_avro: &int_variant_expected_avro(42),
+ })
+ }
+}
+
+mod nullable_record {
+ use super::*;
+
+ const NULLABLE_RECORD_SCHEMA: &str = r#"
+ {
+ "name": "MyUnion",
+ "type": [
+ "null",
+ {
+ "type": "record",
+ "name": "MyRecord",
+ "fields": [
+ {"name": "a", "type": "int"}
+ ]
+ }
+ ]
+ }
+ "#;
+
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct MyRecord {
+ a: i32,
+ }
+
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ enum MyUnionNullable {
+ Null,
+ MyRecord(MyRecord),
+ }
+
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ enum MyUnionAvroJsonEncoding {
+ MyRecord(MyRecord),
+ }
+
+ fn schema() -> Schema {
+ Schema::parse_str(NULLABLE_RECORD_SCHEMA).unwrap()
+ }
+
+ fn null_variant_expected_avro() -> Value {
+ Value::Union(0, Box::new(Value::Null))
+ }
+
+ fn record_variant_expected_avro(a: i32) -> Value {
+ Value::Union(
+ 1,
+ Box::new(Value::Record(vec![("a".to_string(), Value::Int(a))])),
+ )
+ }
+
+ #[test]
+ fn serialize_null_variant_enum_null() -> AvroResult<()> {
+ test_serialize(TestCase {
+ input: MyUnionNullable::Null,
+ schema: &schema(),
+ expected_avro: &null_variant_expected_avro(),
+ })
+ }
+
+ #[test]
+ fn deserialize_null_variant_enum_null() -> AvroResult<()> {
+ test_deserialize(TestCase {
+ input: MyUnionNullable::Null,
+ schema: &schema(),
+ expected_avro: &null_variant_expected_avro(),
+ })
+ }
+
+ #[test]
+ fn serialize_rusty_null() -> AvroResult<()> {
+ test_serialize(TestCase {
+ input: None::<MyRecord>,
+ schema: &schema(),
+ expected_avro: &null_variant_expected_avro(),
+ })
+ }
+
+ #[test]
+ fn deserialize_rusty_null() -> AvroResult<()> {
+ test_deserialize(TestCase {
+ input: None::<MyRecord>,
+ schema: &schema(),
+ expected_avro: &null_variant_expected_avro(),
+ })
+ }
+
+ #[test]
+ fn serialize_avro_json_encoding_compatible_null() -> AvroResult<()> {
+ test_serialize(TestCase {
+ input: None::<MyUnionAvroJsonEncoding>,
+ schema: &schema(),
+ expected_avro: &null_variant_expected_avro(),
+ })
+ }
+
+ #[test]
+ fn deserialize_avro_json_encoding_compatible_null() -> AvroResult<()> {
+ test_deserialize(TestCase {
+ input: None::<MyUnionAvroJsonEncoding>,
+ schema: &schema(),
+ expected_avro: &null_variant_expected_avro(),
+ })
+ }
+
+ #[test]
+ fn serialize_null_variant_enum_my_record_a_27() -> AvroResult<()> {
+ test_serialize(TestCase {
+ input: MyUnionNullable::MyRecord(MyRecord { a: 27 }),
+ schema: &schema(),
+ expected_avro: &record_variant_expected_avro(27),
+ })
+ }
+
+ #[test]
+ fn deserialize_null_variant_enum_my_record_a_27() -> AvroResult<()> {
+ test_deserialize(TestCase {
+ input: MyUnionNullable::MyRecord(MyRecord { a: 27 }),
+ schema: &schema(),
+ expected_avro: &record_variant_expected_avro(27),
+ })
+ }
+
+ #[test]
+ fn serialize_rusty_my_record_a_27() -> AvroResult<()> {
+ test_serialize(TestCase {
+ input: Some(MyRecord { a: 27 }),
+ schema: &schema(),
+ expected_avro: &record_variant_expected_avro(27),
+ })
+ }
+
+ #[test]
+ fn deserialize_rusty_my_record_a_27() -> AvroResult<()> {
+ test_deserialize(TestCase {
+ input: Some(MyRecord { a: 27 }),
+ schema: &schema(),
+ expected_avro: &record_variant_expected_avro(27),
+ })
+ }
+
+ #[test]
+ fn serialize_avro_json_encoding_compatible_my_record_a_27() ->
AvroResult<()> {
+ test_serialize(TestCase {
+ input: Some(MyUnionAvroJsonEncoding::MyRecord(MyRecord { a: 27 })),
+ schema: &schema(),
+ expected_avro: &record_variant_expected_avro(27),
+ })
+ }
+
+ #[test]
+ fn deserialize_avro_json_encoding_compatible_my_record_a_27() ->
AvroResult<()> {
+ test_deserialize(TestCase {
+ input: Some(MyUnionAvroJsonEncoding::MyRecord(MyRecord { a: 27 })),
+ schema: &schema(),
+ expected_avro: &record_variant_expected_avro(27),
+ })
+ }
+}
+
+mod nullable_int_enum_record {
+ use super::*;
+
+ const NULLABLE_INT_ENUM_RECORD_SCHEMA: &str = r#"
+ {
+ "name": "MyUnion",
+ "type": [
+ "null",
+ "int",
+ {
+ "type": "enum",
+ "name": "MyEnum",
+ "symbols": ["A", "B"]
+ },
+ {
+ "type": "record",
+ "name": "MyRecord",
+ "fields": [
+ {"name": "a", "type": "int"}
+ ]
+ }
+ ]
+ }
+ "#;
+
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ enum MyEnum {
+ A,
+ B,
+ }
+
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct MyRecord {
+ a: i32,
+ }
+
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ enum MyUnionNullable {
+ Null,
+ Int(i32),
+ MyEnum(MyEnum),
+ MyRecord(MyRecord),
+ }
+
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ #[serde(untagged)]
+ enum MyUnionUntagged {
+ Int(i32),
+ MyEnum(MyEnum),
+ MyRecord(MyRecord),
+ }
+
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ enum MyUnionAvroJsonEncoding {
+ Int(i32),
+ MyEnum(MyEnum),
+ MyRecord(MyRecord),
+ }
+
+ fn schema() -> Schema {
+ Schema::parse_str(NULLABLE_INT_ENUM_RECORD_SCHEMA).unwrap()
+ }
+
+ fn null_variant_expected_avro() -> Value {
+ Value::Union(0, Box::new(Value::Null))
+ }
+
+ fn int_variant_expected_avro(v: i32) -> Value {
+ Value::Union(1, Box::new(Value::Int(v)))
+ }
+
+ fn a_variant_expected_avro() -> Value {
+ Value::Union(2, Box::new(Value::Enum(0, "A".to_string())))
+ }
+
+ fn record_variant_expected_avro(a: i32) -> Value {
+ Value::Union(
+ 3,
+ Box::new(Value::Record(vec![("a".to_string(), Value::Int(a))])),
+ )
+ }
+
+ #[test]
+ fn serialize_null_variant_enum_null() -> AvroResult<()> {
+ test_serialize(TestCase {
+ input: MyUnionNullable::Null,
+ schema: &schema(),
+ expected_avro: &null_variant_expected_avro(),
+ })
+ }
+
+ #[test]
+ fn deserialize_null_variant_enum_null() -> AvroResult<()> {
+ test_deserialize(TestCase {
+ input: MyUnionNullable::Null,
+ schema: &schema(),
+ expected_avro: &null_variant_expected_avro(),
+ })
+ }
+
+ #[test]
+ fn serialize_rusty_null() -> AvroResult<()> {
+ test_serialize(TestCase {
+ input: None::<MyUnionAvroJsonEncoding>,
+ schema: &schema(),
+ expected_avro: &null_variant_expected_avro(),
+ })
+ }
+
+ #[test]
+ fn deserialize_rusty_null() -> AvroResult<()> {
+ test_deserialize(TestCase {
+ input: None::<MyUnionAvroJsonEncoding>,
+ schema: &schema(),
+ expected_avro: &null_variant_expected_avro(),
+ })
+ }
+
+ #[test]
+ fn serialize_rusty_untagged_null() -> AvroResult<()> {
+ test_serialize(TestCase {
+ input: None::<MyUnionUntagged>,
+ schema: &schema(),
+ expected_avro: &null_variant_expected_avro(),
+ })
+ }
+
+ #[test]
+ fn deserialize_rusty_untagged_null() -> AvroResult<()> {
+ test_deserialize(TestCase {
+ input: None::<MyUnionUntagged>,
+ schema: &schema(),
+ expected_avro: &null_variant_expected_avro(),
+ })
+ }
+
+ #[test]
+ fn serialize_null_variant_enum_int_42() -> AvroResult<()> {
+ test_serialize(TestCase {
+ input: MyUnionNullable::Int(42),
+ schema: &schema(),
+ expected_avro: &int_variant_expected_avro(42),
+ })
+ }
+
+ #[test]
+ fn deserialize_null_variant_enum_int_42() -> AvroResult<()> {
+ test_deserialize(TestCase {
+ input: MyUnionNullable::Int(42),
+ schema: &schema(),
+ expected_avro: &int_variant_expected_avro(42),
+ })
+ }
+
+ #[test]
+ fn serialize_rusty_int_42() -> AvroResult<()> {
+ test_serialize(TestCase {
+ input: Some(MyUnionAvroJsonEncoding::Int(42)),
+ schema: &schema(),
+ expected_avro: &int_variant_expected_avro(42),
+ })
+ }
+
+ #[test]
+ fn deserialize_rusty_int_42() -> AvroResult<()> {
+ test_deserialize(TestCase {
+ input: Some(MyUnionAvroJsonEncoding::Int(42)),
+ schema: &schema(),
+ expected_avro: &int_variant_expected_avro(42),
+ })
+ }
+
+ #[test]
+ fn serialize_rusty_untagged_int_42() -> AvroResult<()> {
+ test_serialize(TestCase {
+ input: Some(MyUnionUntagged::Int(42)),
+ schema: &schema(),
+ expected_avro: &int_variant_expected_avro(42),
+ })
+ }
+
+ #[test]
+ fn deserialize_rusty_untagged_int_42() -> AvroResult<()> {
+ test_deserialize(TestCase {
+ input: Some(MyUnionUntagged::Int(42)),
+ schema: &schema(),
+ expected_avro: &int_variant_expected_avro(42),
+ })
+ }
+
+ #[test]
+ fn serialize_null_variant_enum_my_enum_a() -> AvroResult<()> {
+ test_serialize(TestCase {
+ input: MyUnionNullable::MyEnum(MyEnum::A),
+ schema: &schema(),
+ expected_avro: &a_variant_expected_avro(),
+ })
+ }
+
+ #[test]
+ fn deserialize_null_variant_enum_my_enum_a() -> AvroResult<()> {
+ test_deserialize(TestCase {
+ input: MyUnionNullable::MyEnum(MyEnum::A),
+ schema: &schema(),
+ expected_avro: &a_variant_expected_avro(),
+ })
+ }
+
+ #[test]
+ fn serialize_rusty_my_enum_a() -> AvroResult<()> {
+ test_serialize(TestCase {
+ input: Some(MyUnionAvroJsonEncoding::MyEnum(MyEnum::A)),
+ schema: &schema(),
+ expected_avro: &a_variant_expected_avro(),
+ })
+ }
+
+ #[test]
+ fn deserialize_rusty_my_enum_a() -> AvroResult<()> {
+ test_deserialize(TestCase {
+ input: Some(MyUnionAvroJsonEncoding::MyEnum(MyEnum::A)),
+ schema: &schema(),
+ expected_avro: &a_variant_expected_avro(),
+ })
+ }
+
+ #[test]
+ fn serialize_rusty_untagged_my_enum_a() -> AvroResult<()> {
+ test_serialize(TestCase {
+ input: Some(MyUnionUntagged::MyEnum(MyEnum::A)),
+ schema: &schema(),
+ expected_avro: &a_variant_expected_avro(),
+ })
+ }
+
+ #[test]
+ fn deserialize_rusty_untagged_my_enum_a() -> AvroResult<()> {
+ test_deserialize(TestCase {
+ input: Some(MyUnionUntagged::MyEnum(MyEnum::A)),
+ schema: &schema(),
+ expected_avro: &a_variant_expected_avro(),
+ })
+ }
+
+ #[test]
+ fn serialize_null_variant_enum_my_record_a_27() -> AvroResult<()> {
+ test_serialize(TestCase {
+ input: MyUnionNullable::MyRecord(MyRecord { a: 27 }),
+ schema: &schema(),
+ expected_avro: &record_variant_expected_avro(27),
+ })
+ }
+
+ #[test]
+ fn deserialize_null_variant_enum_my_record_a_27() -> AvroResult<()> {
+ test_deserialize(TestCase {
+ input: MyUnionNullable::MyRecord(MyRecord { a: 27 }),
+ schema: &schema(),
+ expected_avro: &record_variant_expected_avro(27),
+ })
+ }
+
+ #[test]
+ fn serialize_rusty_my_record_a_27() -> AvroResult<()> {
+ test_serialize(TestCase {
+ input: Some(MyUnionAvroJsonEncoding::MyRecord(MyRecord { a: 27 })),
+ schema: &schema(),
+ expected_avro: &record_variant_expected_avro(27),
+ })
+ }
+
+ #[test]
+ fn deserialize_rusty_my_record_a_27() -> AvroResult<()> {
+ test_deserialize(TestCase {
+ input: Some(MyUnionAvroJsonEncoding::MyRecord(MyRecord { a: 27 })),
+ schema: &schema(),
+ expected_avro: &record_variant_expected_avro(27),
+ })
+ }
+
+ #[test]
+ fn serialize_rusty_untagged_my_record_a_27() -> AvroResult<()> {
+ test_serialize(TestCase {
+ input: Some(MyUnionUntagged::MyRecord(MyRecord { a: 27 })),
+ schema: &schema(),
+ expected_avro: &record_variant_expected_avro(27),
+ })
+ }
+
+ #[test]
+ fn deserialize_rusty_untagged_my_record_a_27() -> AvroResult<()> {
+ test_deserialize(TestCase {
+ input: Some(MyUnionUntagged::MyRecord(MyRecord { a: 27 })),
+ schema: &schema(),
+ expected_avro: &record_variant_expected_avro(27),
+ })
+ }
+}
+
+mod nullable_untagged_pitfall {
+ use super::*;
+
+ const NULLABLE_RECORD_SCHEMA: &str = r#"
+ {
+ "name": "MyUnion",
+ "type": [
+ "null",
+ {
+ "type": "record",
+ "name": "MyRecordA",
+ "fields": [
+ {"name": "a", "type": "int"}
+ ]
+ },
+ {
+ "type": "record",
+ "name": "MyRecordB",
+ "fields": [
+ {"name": "a", "type": "int"}
+ ]
+ }
+ ]
+ }
+ "#;
+
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct MyRecordA {
+ a: i32,
+ }
+
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct MyRecordB {
+ a: i32,
+ }
+
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ enum MyUnionNullable {
+ Null,
+ MyRecordA(MyRecordA),
+ MyRecordB(MyRecordB),
+ }
+
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ #[serde(untagged)]
+ enum MyUnionUntagged {
+ MyRecordA(MyRecordA),
+ MyRecordB(MyRecordB),
+ }
+
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ enum MyUnionAvroJsonEncoding {
+ MyRecordA(MyRecordA),
+ MyRecordB(MyRecordB),
+ }
+
+ fn schema() -> Schema {
+ Schema::parse_str(NULLABLE_RECORD_SCHEMA).unwrap()
+ }
+
+ fn record_a_variant_expected_avro(a: i32) -> Value {
+ Value::Union(
+ 1,
+ Box::new(Value::Record(vec![("a".to_string(), Value::Int(a))])),
+ )
+ }
+
+ fn record_b_variant_expected_avro(a: i32) -> Value {
+ Value::Union(
+ 2,
+ Box::new(Value::Record(vec![("a".to_string(), Value::Int(a))])),
+ )
+ }
+
+ #[test]
+ fn serialize_null_variant_enum_my_record_a_27() -> AvroResult<()> {
+ test_serialize(TestCase {
+ input: MyUnionNullable::MyRecordA(MyRecordA { a: 27 }),
+ schema: &schema(),
+ expected_avro: &record_a_variant_expected_avro(27),
+ })
+ }
+
+ #[test]
+ fn deserialize_null_variant_enum_my_record_a_27() -> AvroResult<()> {
+ test_deserialize(TestCase {
+ input: MyUnionNullable::MyRecordA(MyRecordA { a: 27 }),
+ schema: &schema(),
+ expected_avro: &record_a_variant_expected_avro(27),
+ })
+ }
+
+ #[test]
+ fn serialize_rusty_my_record_a_27() -> AvroResult<()> {
+ test_serialize(TestCase {
+ input: Some(MyUnionAvroJsonEncoding::MyRecordA(MyRecordA { a: 27
})),
+ schema: &schema(),
+ expected_avro: &record_a_variant_expected_avro(27),
+ })
+ }
+
+ #[test]
+ fn deserialize_rusty_my_record_a_27() -> AvroResult<()> {
+ test_deserialize(TestCase {
+ input: Some(MyUnionAvroJsonEncoding::MyRecordA(MyRecordA { a: 27
})),
+ schema: &schema(),
+ expected_avro: &record_a_variant_expected_avro(27),
+ })
+ }
+
+ #[test]
+ fn serialize_rusty_untagged_my_record_a_27() -> AvroResult<()> {
+ test_serialize(TestCase {
+ input: Some(MyUnionUntagged::MyRecordA(MyRecordA { a: 27 })),
+ schema: &schema(),
+ expected_avro: &record_a_variant_expected_avro(27),
+ })
+ }
+
+ #[test]
+ fn deserialize_rusty_untagged_my_record_a_27() -> AvroResult<()> {
+ test_deserialize(TestCase {
+ input: Some(MyUnionUntagged::MyRecordA(MyRecordA { a: 27 })),
+ schema: &schema(),
+ expected_avro: &record_a_variant_expected_avro(27),
+ })
+ }
+
+ #[test]
+ fn serialize_null_variant_enum_my_record_b_27() -> AvroResult<()> {
+ test_serialize(TestCase {
+ input: MyUnionNullable::MyRecordB(MyRecordB { a: 27 }),
+ schema: &schema(),
+ expected_avro: &record_b_variant_expected_avro(27),
+ })
+ }
+
+ #[test]
+ fn deserialize_null_variant_enum_my_record_b_27() -> AvroResult<()> {
+ test_deserialize(TestCase {
+ input: MyUnionNullable::MyRecordB(MyRecordB { a: 27 }),
+ schema: &schema(),
+ expected_avro: &record_b_variant_expected_avro(27),
+ })
+ }
+
+ #[test]
+ fn serialize_rusty_my_record_b_27() -> AvroResult<()> {
+ test_serialize(TestCase {
+ input: Some(MyUnionAvroJsonEncoding::MyRecordB(MyRecordB { a: 27
})),
+ schema: &schema(),
+ expected_avro: &record_b_variant_expected_avro(27),
+ })
+ }
+
+ #[test]
+ fn deserialize_rusty_my_record_b_27() -> AvroResult<()> {
+ test_deserialize(TestCase {
+ input: Some(MyUnionAvroJsonEncoding::MyRecordB(MyRecordB { a: 27
})),
+ schema: &schema(),
+ expected_avro: &record_b_variant_expected_avro(27),
+ })
+ }
+
+ #[test]
+ fn serialize_rusty_untagged_my_record_b_27() -> AvroResult<()> {
+ test_serialize(TestCase {
+ input: Some(MyUnionUntagged::MyRecordB(MyRecordB { a: 27 })),
+ schema: &schema(),
+ expected_avro: &record_b_variant_expected_avro(27),
+ })
+ }
+
+ #[test]
+ #[ignore]
Review Comment:
Updated to instead expect a failure / comment on why it will fail. I'm also
open to just removing it if you think its out of scope, since that mod is
mostly to demonstrate how untagged enums has edge cases that fail and check
that tagged enums do not
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]