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)