[ 
https://issues.apache.org/jira/browse/AVRO-3786?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17742839#comment-17742839
 ] 

Evan Blackwell edited comment on AVRO-3786 at 7/13/23 3:18 PM:
---------------------------------------------------------------

This issue still persists if the enum is defined in the record instead of 
referenced from another definition.

 

This test will pass when the symbol is known by the reader and writer and is at 
the same position

 
{code:java}
#[test]
    fn deserialize_union_with_different_enum_order_defined_in_record() -> 
TestResult {
        #[derive(Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Clone, 
serde::Deserialize, serde::Serialize)]
        pub enum Bar {
            #[serde(rename = "bar0")]
            Bar0,
            #[serde(rename = "bar1")]
            Bar1,
            #[serde(rename = "bar2")]
            Bar2,
        }
        #[derive(Debug, PartialEq, Eq, Clone, serde::Deserialize, 
serde::Serialize)]
        pub struct BarParent {
            pub bar: Bar,
        }
        #[derive(Debug, PartialEq, Eq, Clone, serde::Deserialize, 
serde::Serialize)]
        pub struct Foo {
            #[serde(rename = "barParent")]
            pub bar_parent: Option<BarParent>,
        }
        let writer_schema = r#"{
            "type": "record",
            "name": "Foo",
            "namespace": "com.rallyhealth.devices.canonical.avro.model.v6_0",
            "fields":
            [
                {
                    "name": "barParent",
                    "type": [
                        "null",
                        {
                            "type": "record",
                            "name": "BarParent",
                            "fields": [
                                {
                                    "name": "bar",
                                    "type": {
                                        "type": "enum",
                                        "name": "Bar",
                                        "symbols":
                                        [
                                            "bar0",
                                            "bar1",
                                            "bar2"
                                        ],
                                        "default": "bar0"
                                    }
                                }
                            ]
                        }
                    ]
                }
            ]
        }"#;
        let reader_schema = r#"{
            "type": "record",
            "name": "Foo",
            "namespace": "com.rallyhealth.devices.canonical.avro.model.v6_0",
            "fields":
            [
                {
                    "name": "barParent",
                    "type": [
                        "null",
                        {
                            "type": "record",
                            "name": "BarParent",
                            "fields": [
                                {
                                    "name": "bar",
                                    "type": {
                                        "type": "enum",
                                        "name": "Bar",
                                        "symbols":
                                        [
                                            "bar0",
                                            "bar2"
                                        ],
                                        "default": "bar0"
                                    }
                                }
                            ]
                        }
                    ]
                }
            ]
        }"#;
        let writer_schema = Schema::parse_str(writer_schema)?;
        let foo = Foo {
            bar_parent: Some(BarParent { bar: Bar::Bar0} ),
        };
        let avro_value = crate::to_value(foo)?;
        assert!(
            avro_value.validate(&writer_schema),
            "value is valid for schema",
        );
        let datum = crate::to_avro_datum(&writer_schema, avro_value)?;
        let mut x = &datum[..];
        let reader_schema = Schema::parse_str(reader_schema)?;
        let deser_value = crate::from_avro_datum(&writer_schema, &mut x, 
Some(&reader_schema))?;
        match deser_value {
            types::Value::Record(fields) => {
                assert_eq!(fields.len(), 1);
                assert_eq!(fields[0].0, "barParent");
                // TODO: better validation
            }
            _ => panic!("Expected Value::Record"),
        }        Ok(())
    } {code}
 

 

This test that gives a symbol unknown to the reader fails even though it has a 
default. It fails with this error: "Message:  apache_avro::error::Error: Could 
not find matching type in union"
{code:java}
#[test]
    fn deserialize_union_with_different_enum_order_defined_in_record() -> 
TestResult {
        #[derive(Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Clone, 
serde::Deserialize, serde::Serialize)]
        pub enum Bar {
            #[serde(rename = "bar0")]
            Bar0,
            #[serde(rename = "bar1")]
            Bar1,
            #[serde(rename = "bar2")]
            Bar2,
        }
        #[derive(Debug, PartialEq, Eq, Clone, serde::Deserialize, 
serde::Serialize)]
        pub struct BarParent {
            pub bar: Bar,
        }
        #[derive(Debug, PartialEq, Eq, Clone, serde::Deserialize, 
serde::Serialize)]
        pub struct Foo {
            #[serde(rename = "barParent")]
            pub bar_parent: Option<BarParent>,
        }
        let writer_schema = r#"{
            "type": "record",
            "name": "Foo",
            "namespace": "com.rallyhealth.devices.canonical.avro.model.v6_0",
            "fields":
            [
                {
                    "name": "barParent",
                    "type": [
                        "null",
                        {
                            "type": "record",
                            "name": "BarParent",
                            "fields": [
                                {
                                    "name": "bar",
                                    "type": {
                                        "type": "enum",
                                        "name": "Bar",
                                        "symbols":
                                        [
                                            "bar0",
                                            "bar1",
                                            "bar2"
                                        ],
                                        "default": "bar0"
                                    }
                                }
                            ]
                        }
                    ]
                }
            ]
        }"#;
        let reader_schema = r#"{
            "type": "record",
            "name": "Foo",
            "namespace": "com.rallyhealth.devices.canonical.avro.model.v6_0",
            "fields":
            [
                {
                    "name": "barParent",
                    "type": [
                        "null",
                        {
                            "type": "record",
                            "name": "BarParent",
                            "fields": [
                                {
                                    "name": "bar",
                                    "type": {
                                        "type": "enum",
                                        "name": "Bar",
                                        "symbols":
                                        [
                                            "bar0",
                                            "bar2"
                                        ],
                                        "default": "bar0"
                                    }
                                }
                            ]
                        }
                    ]
                }
            ]
        }"#;
        let writer_schema = Schema::parse_str(writer_schema)?;
        let foo = Foo {
            bar_parent: Some(BarParent { bar: Bar::Bar1} ),
        };
        let avro_value = crate::to_value(foo)?;
        assert!(
            avro_value.validate(&writer_schema),
            "value is valid for schema",
        );
        let datum = crate::to_avro_datum(&writer_schema, avro_value)?;
        let mut x = &datum[..];
        let reader_schema = Schema::parse_str(reader_schema)?;
        let deser_value = crate::from_avro_datum(&writer_schema, &mut x, 
Some(&reader_schema))?;
        match deser_value {
            types::Value::Record(fields) => {
                assert_eq!(fields.len(), 1);
                assert_eq!(fields[0].0, "barParent");
                // TODO: better validation
            }
            _ => panic!("Expected Value::Record"),
        }
        Ok(())
    } {code}
This test uses a symbol that both the reader and writer know, but they have a 
different index. It fails with the same error. 
{code:java}
#[test]
    fn deserialize_union_with_different_enum_order_defined_in_record() -> 
TestResult {
        #[derive(Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Clone, 
serde::Deserialize, serde::Serialize)]
        pub enum Bar {
            #[serde(rename = "bar0")]
            Bar0,
            #[serde(rename = "bar1")]
            Bar1,
            #[serde(rename = "bar2")]
            Bar2,
        }
        #[derive(Debug, PartialEq, Eq, Clone, serde::Deserialize, 
serde::Serialize)]
        pub struct BarParent {
            pub bar: Bar,
        }
        #[derive(Debug, PartialEq, Eq, Clone, serde::Deserialize, 
serde::Serialize)]
        pub struct Foo {
            #[serde(rename = "barParent")]
            pub bar_parent: Option<BarParent>,
        }        let writer_schema = r#"{
            "type": "record",
            "name": "Foo",
            "namespace": "com.rallyhealth.devices.canonical.avro.model.v6_0",
            "fields":
            [
                {
                    "name": "barParent",
                    "type": [
                        "null",
                        {
                            "type": "record",
                            "name": "BarParent",
                            "fields": [
                                {
                                    "name": "bar",
                                    "type": {
                                        "type": "enum",
                                        "name": "Bar",
                                        "symbols":
                                        [
                                            "bar0",
                                            "bar1",
                                            "bar2"
                                        ],
                                        "default": "bar2"
                                    }
                                }
                            ]
                        }
                    ]
                }
            ]
        }"#;
        let reader_schema = r#"{
            "type": "record",
            "name": "Foo",
            "namespace": "com.rallyhealth.devices.canonical.avro.model.v6_0",
            "fields":
            [
                {
                    "name": "barParent",
                    "type": [
                        "null",
                        {
                            "type": "record",
                            "name": "BarParent",
                            "fields": [
                                {
                                    "name": "bar",
                                    "type": {
                                        "type": "enum",
                                        "name": "Bar",
                                        "symbols":
                                        [
                                            "bar1",
                                            "bar2"
                                        ],
                                        "default": "bar2"
                                    }
                                }
                            ]
                        }
                    ]
                }
            ]
        }"#;
        let writer_schema = Schema::parse_str(writer_schema)?;
        let foo = Foo {
            bar_parent: Some(BarParent { bar: Bar::Bar1} ),
        };
        let avro_value = crate::to_value(foo)?;
        assert!(
            avro_value.validate(&writer_schema),
            "value is valid for schema",
        );
        let datum = crate::to_avro_datum(&writer_schema, avro_value)?;
        let mut x = &datum[..];
        let reader_schema = Schema::parse_str(reader_schema)?;
        let deser_value = crate::from_avro_datum(&writer_schema, &mut x, 
Some(&reader_schema))?;
        match deser_value {
            types::Value::Record(fields) => {
                assert_eq!(fields.len(), 1);
                assert_eq!(fields[0].0, "barParent");
                // TODO: better validation
            }
            _ => panic!("Expected Value::Record"),
        }        Ok(())
    } {code}
This test also uses a symbol that both the reader and writer know, but they 
have a different index. However, it passes. It's different than the previous 
test in a few ways: this shared value has index 0 in the reader while they both 
had the last index in the previous test, and the default is different.
{code:java}
#[test]
    fn deserialize_union_with_different_enum_order_defined_in_record() -> 
TestResult {
        #[derive(Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Clone, 
serde::Deserialize, serde::Serialize)]
        pub enum Bar {
            #[serde(rename = "bar0")]
            Bar0,
            #[serde(rename = "bar1")]
            Bar1,
            #[serde(rename = "bar2")]
            Bar2,
        }
        #[derive(Debug, PartialEq, Eq, Clone, serde::Deserialize, 
serde::Serialize)]
        pub struct BarParent {
            pub bar: Bar,
        }
        #[derive(Debug, PartialEq, Eq, Clone, serde::Deserialize, 
serde::Serialize)]
        pub struct Foo {
            #[serde(rename = "barParent")]
            pub bar_parent: Option<BarParent>,
        }
        let writer_schema = r#"{
            "type": "record",
            "name": "Foo",
            "namespace": "com.rallyhealth.devices.canonical.avro.model.v6_0",
            "fields":
            [
                {
                    "name": "barParent",
                    "type": [
                        "null",
                        {
                            "type": "record",
                            "name": "BarParent",
                            "fields": [
                                {
                                    "name": "bar",
                                    "type": {
                                        "type": "enum",
                                        "name": "Bar",
                                        "symbols":
                                        [
                                            "bar0",
                                            "bar1",
                                            "bar2"
                                        ],
                                        "default": "bar0"
                                    }
                                }
                            ]
                        }
                    ]
                }
            ]
        }"#;
        let reader_schema = r#"{
            "type": "record",
            "name": "Foo",
            "namespace": "com.rallyhealth.devices.canonical.avro.model.v6_0",
            "fields":
            [
                {
                    "name": "barParent",
                    "type": [
                        "null",
                        {
                            "type": "record",
                            "name": "BarParent",
                            "fields": [
                                {
                                    "name": "bar",
                                    "type": {
                                        "type": "enum",
                                        "name": "Bar",
                                        "symbols":
                                        [
                                            "bar0",
                                            "bar2"
                                        ],
                                        "default": "bar0"
                                    }
                                }
                            ]
                        }
                    ]
                }
            ]
        }"#;
        let writer_schema = Schema::parse_str(writer_schema)?;
        let foo = Foo {
            bar_parent: Some(BarParent { bar: Bar::Bar2} ),
        };
        let avro_value = crate::to_value(foo)?;
        assert!(
            avro_value.validate(&writer_schema),
            "value is valid for schema",
        );
        let datum = crate::to_avro_datum(&writer_schema, avro_value)?;
        let mut x = &datum[..];
        let reader_schema = Schema::parse_str(reader_schema)?;
        let deser_value = crate::from_avro_datum(&writer_schema, &mut x, 
Some(&reader_schema))?;
        match deser_value {
            types::Value::Record(fields) => {
                assert_eq!(fields.len(), 1);
                assert_eq!(fields[0].0, "barParent");
                // TODO: better validation
            }
            _ => panic!("Expected Value::Record"),
        }
        Ok(())
    } {code}


was (Author: JIRAUSER300776):
This issue still persists if the enum is defined in the record instead of 
referenced from another definition.

 

This test will pass when the symbol is known by the reader and writer and is at 
the same position

 
{code:java}
#[test]
    fn deserialize_union_with_different_enum_order_defined_in_record() -> 
TestResult {
        #[derive(Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Clone, 
serde::Deserialize, serde::Serialize)]
        pub enum Bar {
            #[serde(rename = "bar0")]
            Bar0,
            #[serde(rename = "bar1")]
            Bar1,
            #[serde(rename = "bar2")]
            Bar2,
        }
        #[derive(Debug, PartialEq, Eq, Clone, serde::Deserialize, 
serde::Serialize)]
        pub struct BarParent {
            pub bar: Bar,
        }
        #[derive(Debug, PartialEq, Eq, Clone, serde::Deserialize, 
serde::Serialize)]
        pub struct Foo {
            #[serde(rename = "barParent")]
            pub bar_parent: Option<BarParent>,
        }
        let writer_schema = r#"{
            "type": "record",
            "name": "Foo",
            "namespace": "com.rallyhealth.devices.canonical.avro.model.v6_0",
            "fields":
            [
                {
                    "name": "barParent",
                    "type": [
                        "null",
                        {
                            "type": "record",
                            "name": "BarParent",
                            "fields": [
                                {
                                    "name": "bar",
                                    "type": {
                                        "type": "enum",
                                        "name": "Bar",
                                        "symbols":
                                        [
                                            "bar0",
                                            "bar1",
                                            "bar2"
                                        ],
                                        "default": "bar0"
                                    }
                                }
                            ]
                        }
                    ]
                }
            ]
        }"#;
        let reader_schema = r#"{
            "type": "record",
            "name": "Foo",
            "namespace": "com.rallyhealth.devices.canonical.avro.model.v6_0",
            "fields":
            [
                {
                    "name": "barParent",
                    "type": [
                        "null",
                        {
                            "type": "record",
                            "name": "BarParent",
                            "fields": [
                                {
                                    "name": "bar",
                                    "type": {
                                        "type": "enum",
                                        "name": "Bar",
                                        "symbols":
                                        [
                                            "bar0",
                                            "bar2"
                                        ],
                                        "default": "bar0"
                                    }
                                }
                            ]
                        }
                    ]
                }
            ]
        }"#;
        let writer_schema = Schema::parse_str(writer_schema)?;
        let foo = Foo {
            bar_parent: Some(BarParent { bar: Bar::Bar0} ),
        };
        let avro_value = crate::to_value(foo)?;
        assert!(
            avro_value.validate(&writer_schema),
            "value is valid for schema",
        );
        let datum = crate::to_avro_datum(&writer_schema, avro_value)?;
        let mut x = &datum[..];
        let reader_schema = Schema::parse_str(reader_schema)?;
        let deser_value = crate::from_avro_datum(&writer_schema, &mut x, 
Some(&reader_schema))?;
        match deser_value {
            types::Value::Record(fields) => {
                assert_eq!(fields.len(), 1);
                assert_eq!(fields[0].0, "barParent");
                // TODO: better validation
            }
            _ => panic!("Expected Value::Record"),
        }        Ok(())
    } {code}
 

 

This test that gives a symbol unknown to the reader fails even though it has a 
default. 
{code:java}
#[test]
    fn deserialize_union_with_different_enum_order_defined_in_record() -> 
TestResult {
        #[derive(Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Clone, 
serde::Deserialize, serde::Serialize)]
        pub enum Bar {
            #[serde(rename = "bar0")]
            Bar0,
            #[serde(rename = "bar1")]
            Bar1,
            #[serde(rename = "bar2")]
            Bar2,
        }
        #[derive(Debug, PartialEq, Eq, Clone, serde::Deserialize, 
serde::Serialize)]
        pub struct BarParent {
            pub bar: Bar,
        }
        #[derive(Debug, PartialEq, Eq, Clone, serde::Deserialize, 
serde::Serialize)]
        pub struct Foo {
            #[serde(rename = "barParent")]
            pub bar_parent: Option<BarParent>,
        }
        let writer_schema = r#"{
            "type": "record",
            "name": "Foo",
            "namespace": "com.rallyhealth.devices.canonical.avro.model.v6_0",
            "fields":
            [
                {
                    "name": "barParent",
                    "type": [
                        "null",
                        {
                            "type": "record",
                            "name": "BarParent",
                            "fields": [
                                {
                                    "name": "bar",
                                    "type": {
                                        "type": "enum",
                                        "name": "Bar",
                                        "symbols":
                                        [
                                            "bar0",
                                            "bar1",
                                            "bar2"
                                        ],
                                        "default": "bar0"
                                    }
                                }
                            ]
                        }
                    ]
                }
            ]
        }"#;
        let reader_schema = r#"{
            "type": "record",
            "name": "Foo",
            "namespace": "com.rallyhealth.devices.canonical.avro.model.v6_0",
            "fields":
            [
                {
                    "name": "barParent",
                    "type": [
                        "null",
                        {
                            "type": "record",
                            "name": "BarParent",
                            "fields": [
                                {
                                    "name": "bar",
                                    "type": {
                                        "type": "enum",
                                        "name": "Bar",
                                        "symbols":
                                        [
                                            "bar0",
                                            "bar2"
                                        ],
                                        "default": "bar0"
                                    }
                                }
                            ]
                        }
                    ]
                }
            ]
        }"#;
        let writer_schema = Schema::parse_str(writer_schema)?;
        let foo = Foo {
            bar_parent: Some(BarParent { bar: Bar::Bar1} ),
        };
        let avro_value = crate::to_value(foo)?;
        assert!(
            avro_value.validate(&writer_schema),
            "value is valid for schema",
        );
        let datum = crate::to_avro_datum(&writer_schema, avro_value)?;
        let mut x = &datum[..];
        let reader_schema = Schema::parse_str(reader_schema)?;
        let deser_value = crate::from_avro_datum(&writer_schema, &mut x, 
Some(&reader_schema))?;
        match deser_value {
            types::Value::Record(fields) => {
                assert_eq!(fields.len(), 1);
                assert_eq!(fields[0].0, "barParent");
                // TODO: better validation
            }
            _ => panic!("Expected Value::Record"),
        }
        Ok(())
    } {code}
This test uses a symbol that both the reader and writer know, but they have a 
different index. It fails with the same error. "Message:  
apache_avro::error::Error: Could not find matching type in union"
{code:java}
#[test]
    fn deserialize_union_with_different_enum_order_defined_in_record() -> 
TestResult {
        #[derive(Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Clone, 
serde::Deserialize, serde::Serialize)]
        pub enum Bar {
            #[serde(rename = "bar0")]
            Bar0,
            #[serde(rename = "bar1")]
            Bar1,
            #[serde(rename = "bar2")]
            Bar2,
        }
        #[derive(Debug, PartialEq, Eq, Clone, serde::Deserialize, 
serde::Serialize)]
        pub struct BarParent {
            pub bar: Bar,
        }
        #[derive(Debug, PartialEq, Eq, Clone, serde::Deserialize, 
serde::Serialize)]
        pub struct Foo {
            #[serde(rename = "barParent")]
            pub bar_parent: Option<BarParent>,
        }        let writer_schema = r#"{
            "type": "record",
            "name": "Foo",
            "namespace": "com.rallyhealth.devices.canonical.avro.model.v6_0",
            "fields":
            [
                {
                    "name": "barParent",
                    "type": [
                        "null",
                        {
                            "type": "record",
                            "name": "BarParent",
                            "fields": [
                                {
                                    "name": "bar",
                                    "type": {
                                        "type": "enum",
                                        "name": "Bar",
                                        "symbols":
                                        [
                                            "bar0",
                                            "bar1",
                                            "bar2"
                                        ],
                                        "default": "bar2"
                                    }
                                }
                            ]
                        }
                    ]
                }
            ]
        }"#;
        let reader_schema = r#"{
            "type": "record",
            "name": "Foo",
            "namespace": "com.rallyhealth.devices.canonical.avro.model.v6_0",
            "fields":
            [
                {
                    "name": "barParent",
                    "type": [
                        "null",
                        {
                            "type": "record",
                            "name": "BarParent",
                            "fields": [
                                {
                                    "name": "bar",
                                    "type": {
                                        "type": "enum",
                                        "name": "Bar",
                                        "symbols":
                                        [
                                            "bar1",
                                            "bar2"
                                        ],
                                        "default": "bar2"
                                    }
                                }
                            ]
                        }
                    ]
                }
            ]
        }"#;
        let writer_schema = Schema::parse_str(writer_schema)?;
        let foo = Foo {
            bar_parent: Some(BarParent { bar: Bar::Bar1} ),
        };
        let avro_value = crate::to_value(foo)?;
        assert!(
            avro_value.validate(&writer_schema),
            "value is valid for schema",
        );
        let datum = crate::to_avro_datum(&writer_schema, avro_value)?;
        let mut x = &datum[..];
        let reader_schema = Schema::parse_str(reader_schema)?;
        let deser_value = crate::from_avro_datum(&writer_schema, &mut x, 
Some(&reader_schema))?;
        match deser_value {
            types::Value::Record(fields) => {
                assert_eq!(fields.len(), 1);
                assert_eq!(fields[0].0, "barParent");
                // TODO: better validation
            }
            _ => panic!("Expected Value::Record"),
        }        Ok(())
    } {code}
This test also uses a symbol that both the reader and writer know, but they 
have a different index. However, it passes. It's different than the previous 
test in a few ways: this shared value has index 0 in the reader while they both 
had the last index in the previous test, and the default is different.
{code:java}
#[test]
    fn deserialize_union_with_different_enum_order_defined_in_record() -> 
TestResult {
        #[derive(Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Clone, 
serde::Deserialize, serde::Serialize)]
        pub enum Bar {
            #[serde(rename = "bar0")]
            Bar0,
            #[serde(rename = "bar1")]
            Bar1,
            #[serde(rename = "bar2")]
            Bar2,
        }
        #[derive(Debug, PartialEq, Eq, Clone, serde::Deserialize, 
serde::Serialize)]
        pub struct BarParent {
            pub bar: Bar,
        }
        #[derive(Debug, PartialEq, Eq, Clone, serde::Deserialize, 
serde::Serialize)]
        pub struct Foo {
            #[serde(rename = "barParent")]
            pub bar_parent: Option<BarParent>,
        }
        let writer_schema = r#"{
            "type": "record",
            "name": "Foo",
            "namespace": "com.rallyhealth.devices.canonical.avro.model.v6_0",
            "fields":
            [
                {
                    "name": "barParent",
                    "type": [
                        "null",
                        {
                            "type": "record",
                            "name": "BarParent",
                            "fields": [
                                {
                                    "name": "bar",
                                    "type": {
                                        "type": "enum",
                                        "name": "Bar",
                                        "symbols":
                                        [
                                            "bar0",
                                            "bar1",
                                            "bar2"
                                        ],
                                        "default": "bar0"
                                    }
                                }
                            ]
                        }
                    ]
                }
            ]
        }"#;
        let reader_schema = r#"{
            "type": "record",
            "name": "Foo",
            "namespace": "com.rallyhealth.devices.canonical.avro.model.v6_0",
            "fields":
            [
                {
                    "name": "barParent",
                    "type": [
                        "null",
                        {
                            "type": "record",
                            "name": "BarParent",
                            "fields": [
                                {
                                    "name": "bar",
                                    "type": {
                                        "type": "enum",
                                        "name": "Bar",
                                        "symbols":
                                        [
                                            "bar0",
                                            "bar2"
                                        ],
                                        "default": "bar0"
                                    }
                                }
                            ]
                        }
                    ]
                }
            ]
        }"#;
        let writer_schema = Schema::parse_str(writer_schema)?;
        let foo = Foo {
            bar_parent: Some(BarParent { bar: Bar::Bar2} ),
        };
        let avro_value = crate::to_value(foo)?;
        assert!(
            avro_value.validate(&writer_schema),
            "value is valid for schema",
        );
        let datum = crate::to_avro_datum(&writer_schema, avro_value)?;
        let mut x = &datum[..];
        let reader_schema = Schema::parse_str(reader_schema)?;
        let deser_value = crate::from_avro_datum(&writer_schema, &mut x, 
Some(&reader_schema))?;
        match deser_value {
            types::Value::Record(fields) => {
                assert_eq!(fields.len(), 1);
                assert_eq!(fields[0].0, "barParent");
                // TODO: better validation
            }
            _ => panic!("Expected Value::Record"),
        }
        Ok(())
    } {code}

> [Rust] Deserialization results in FindUnionVariant error if the writer and 
> reader have the same symbol but at different positions
> ---------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: AVRO-3786
>                 URL: https://issues.apache.org/jira/browse/AVRO-3786
>             Project: Apache Avro
>          Issue Type: Bug
>          Components: rust
>            Reporter: Evan Blackwell
>            Assignee: Martin Tzvetanov Grigorov
>            Priority: Major
>              Labels: pull-request-available
>             Fix For: 1.12.0, 1.11.3
>
>          Time Spent: 20m
>  Remaining Estimate: 0h
>
> When calling from_avro_datum with a reader schema that has the same enum 
> symbol but in a different position as the writer schema, a FindUnionVariant 
> error occurs. The value in the message is available in both schemas. The enum 
> is defined elsewhere in the schema, so it's worth checking if the problem is 
> with the reference type or the enum itself.
>  
> Sample test
> {code:java}
> #[test]
>     fn deserialize_union_with_different_enum_order() -> TestResult {
>         #[derive(Debug, PartialEq, Eq, Clone, serde::Deserialize, 
> serde::Serialize)]
>         pub struct BarUseParent {
>             #[serde(rename = "barUse")]
>             pub bar_use: Bar,
>         }
>         #[derive(Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Clone, 
> serde::Deserialize, serde::Serialize)]
>         pub enum Bar {
>             #[serde(rename = "bar0")]
>             Bar0,
>             #[serde(rename = "bar1")]
>             Bar1,
>             #[serde(rename = "bar2")]
>             Bar2,
>         }
>         #[derive(Debug, PartialEq, Eq, Clone, serde::Deserialize, 
> serde::Serialize)]
>         pub struct Foo {
>             #[serde(rename = "barInit")]
>             pub bar_init: Bar,
>             #[serde(rename = "barUseParent")]
>             pub bar_use_parent: Option<BarUseParent>,
>         }
>         let writer_schema = r#"{
>             "type": "record",
>             "name": "Foo",
>             "fields":
>             [
>                 {
>                     "name": "barInit",
>                     "type":
>                     {
>                         "type": "enum",
>                         "name": "Bar",
>                         "symbols":
>                         [
>                             "bar0",
>                             "bar1",
>                             "bar2"
>                         ],
>                         "default": "bar0"
>                     }
>                 },
>                 {
>                     "name": "barUseParent",
>                     "type": [
>                         "null",
>                         {
>                             "type": "record",
>                             "name": "BarUseParent",
>                             "fields": [
>                                 {
>                                     "name": "barUse",
>                                     "type": "Bar"
>                                 }
>                             ]
>                         }
>                     ]
>                 }
>             ]
>         }"#;
>         let reader_schema = r#"{
>             "type": "record",
>             "name": "Foo",
>             "fields":
>             [
>                 {
>                     "name": "barInit",
>                     "type":
>                     {
>                         "type": "enum",
>                         "name": "Bar",
>                         "symbols":
>                         [
>                             "bar1"
>                         ],
>                         "default": "bar1"
>                     }
>                 },
>                 {
>                     "name": "barUseParent",
>                     "type": [
>                         "null",
>                         {
>                             "type": "record",
>                             "name": "BarUseParent",
>                             "fields": [
>                                 {
>                                     "name": "barUse",
>                                     "type": "Bar"
>                                 }
>                             ]
>                         }
>                     ]
>                 }
>             ]
>             }"#;
>         let writer_schema = Schema::parse_str(writer_schema)?;
>         let foo = Foo {
>             bar_init: Bar::Bar1,
>             bar_use_parent: Some(BarUseParent { bar_use: Bar::Bar1} ),
>         };
>         let avro_value = crate::to_value(foo)?;
>         assert!(
>             avro_value.validate(&writer_schema),
>             "value is valid for schema",
>         );
>         let datum = crate::to_avro_datum(&writer_schema, avro_value)?;
>         let mut x = &datum[..];
>         let reader_schema = Schema::parse_str(reader_schema)?;
>         let deser_value = crate::from_avro_datum(&writer_schema, &mut x, 
> Some(&reader_schema))?;
>         match deser_value {
>             types::Value::Record(fields) => {
>                 assert_eq!(fields.len(), 2);
>                 assert_eq!(fields[0].0, "barInit");
>                 assert_eq!(fields[0].1, types::Value::Enum(1, 
> "bar1".to_string()));
>                 assert_eq!(fields[1].0, "barUseParent");
>                 // TODO: assert barUseParent value
>             }
>             _ => panic!("Expected Value::Record"),
>         }        Ok(())
>     }         Ok(())    } {code}
> Resulting error:
> {code:java}
> apache_avro::error::Error: Could not find matching type in union {code}



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to