You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@avro.apache.org by "ASF GitHub Bot (Jira)" <ji...@apache.org> on 2022/10/19 12:36:00 UTC

[jira] [Updated] (AVRO-3645) Fix deserialization of enum with unit () type

     [ https://issues.apache.org/jira/browse/AVRO-3645?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

ASF GitHub Bot updated AVRO-3645:
---------------------------------
    Labels: pull-request-available rust  (was: rust)

> Fix deserialization of enum with unit () type
> ---------------------------------------------
>
>                 Key: AVRO-3645
>                 URL: https://issues.apache.org/jira/browse/AVRO-3645
>             Project: Apache Avro
>          Issue Type: Bug
>          Components: rust
>            Reporter: Lucas Javaudin
>            Priority: Major
>              Labels: pull-request-available, rust
>   Original Estimate: 2h
>          Time Spent: 10m
>  Remaining Estimate: 1h 50m
>
> Consider the following test:
> {code:java}
> #[derive(Debug, Deserialize, Serialize, PartialEq, Eq)]
> struct TestNullExternalEnum {
>     a: NullExternalEnum,
> }    
> #[derive(Debug, Deserialize, Serialize, PartialEq, Eq)]
> enum NullExternalEnum {
>     Val1(()),
>     Val2(u64),
> }
> #[test]
> fn test_from_value_null_enum() {
>     let expected = TestNullExternalEnum {
>         a: NullExternalEnum::Val1(()),
>     };
>     let test = Value::Record(vec![(
>         "a".to_owned(),
>         Value::Record(vec![
>             ("type".to_owned(), Value::String("Val1".to_owned())),
>             ("value".to_owned(), Value::Union(0, Box::new(Value::Null))),
>         ]),
>     )]);
>     let final_value: TestNullExternalEnum = from_value(&test).unwrap();
>     assert_eq!(
>         final_value, expected,
>         "Error deserializing null external enum"
>     );
> }{code}
> On version `0.15.0`, it fails with the following error message:
> {code:java}
> called `Result::unwrap()` on an `Err` value: DeserializeValue("not a null") {code}
>  
> If my understanding is correct, it fails because rust is expecting a `Value::Null` but it got a `Value::Union(0, Box::new(Value::Null))`.
> A fix that I found is to replace the `deserialize_unit`function in `de.rs` from
> {code:java}
> fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error>
> where
>     V: Visitor<'de>,
> {
>     match *self.input {
>         Value::Null => visitor.visit_unit(),
>         _ => Err(de::Error::custom("not a null")),
>     }
> } {code}
> to
> {code:java}
> fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error>
> where
>     V: Visitor<'de>,
> {
>     match *self.input {
>         Value::Null => visitor.visit_unit(),
>         Value::Union(_i, ref x) => match **x {
>             Value::Null => visitor.visit_unit(),
>             _ => Err(de::Error::custom("not a null")),
>         },
>         _ => Err(de::Error::custom("not a null")),
>     }
> } {code}
> i.e., we allow it to accept `Value::Union`, in the same way that the `deserialize_string` function accepts such values.
>  
> If you ask yourself what is the point of having an enum with unit type, it is because apache-avro is not able to handle the following enum (as far as I know):
> {code:java}
> enum NullExternalEnum {
>     Val1,
>     Val2(u64),
> } {code}
> I am sorry if there is any problem with this issue, it's the first time I open an issue here.



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