Lucas Javaudin created AVRO-3645:
------------------------------------
Summary: 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
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)