You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@avro.apache.org by mg...@apache.org on 2022/02/01 11:51:38 UTC

[avro] 23/30: AVRO-3312: Use u32 instead of i32 for the Enum/Union's index field (#1465)

This is an automated email from the ASF dual-hosted git repository.

mgrigorov pushed a commit to branch branch-1.11
in repository https://gitbox.apache.org/repos/asf/avro.git

commit 5af11f3c70ed93a19ed77cf6a48351bacdae215d
Author: Martin Grigorov <ma...@users.noreply.github.com>
AuthorDate: Wed Jan 19 21:20:52 2022 +0200

    AVRO-3312: Use u32 instead of i32 for the Enum/Union's index field (#1465)
    
    (cherry picked from commit e2eb392b5f080b7703d8bac35f6a478403d6f9af)
---
 lang/rust/src/decode.rs |  4 ++--
 lang/rust/src/encode.rs |  2 +-
 lang/rust/src/error.rs  |  3 +++
 lang/rust/src/ser.rs    | 21 +++++++++------------
 lang/rust/src/types.rs  | 12 ++++++------
 5 files changed, 21 insertions(+), 21 deletions(-)

diff --git a/lang/rust/src/decode.rs b/lang/rust/src/decode.rs
index eb9c018..70c1ba5 100644
--- a/lang/rust/src/decode.rs
+++ b/lang/rust/src/decode.rs
@@ -215,7 +215,7 @@ pub fn decode<R: Read>(schema: &Schema, reader: &mut R) -> AvroResult<Value> {
                             num_variants: variants.len(),
                         })?;
                     let value = decode0(variant, reader, schemas_by_name)?;
-                    Ok(Value::Union(index as i32, Box::new(value)))
+                    Ok(Value::Union(index as u32, Box::new(value)))
                 }
                 Err(Error::ReadVariableIntegerBytes(io_err)) => {
                     if let ErrorKind::UnexpectedEof = io_err.kind() {
@@ -254,7 +254,7 @@ pub fn decode<R: Read>(schema: &Schema, reader: &mut R) -> AvroResult<Value> {
                         .map_err(|e| Error::ConvertI32ToUsize(e, raw_index))?;
                     if (0..=symbols.len()).contains(&index) {
                         let symbol = symbols[index].clone();
-                        Value::Enum(raw_index, symbol)
+                        Value::Enum(raw_index as u32, symbol)
                     } else {
                         return Err(Error::GetEnumValue {
                             index,
diff --git a/lang/rust/src/encode.rs b/lang/rust/src/encode.rs
index 9a1fbef..6fc969a 100644
--- a/lang/rust/src/encode.rs
+++ b/lang/rust/src/encode.rs
@@ -123,7 +123,7 @@ pub fn encode_ref(value: &Value, schema: &Schema, buffer: &mut Vec<u8>) {
                 _ => error!("invalid schema type for String: {:?}", schema),
             },
             Value::Fixed(_, bytes) => buffer.extend(bytes),
-            Value::Enum(i, _) => encode_int(*i, buffer),
+            Value::Enum(i, _) => encode_int(*i as i32, buffer),
             Value::Union(idx, item) => {
                 if let Schema::Union(ref inner) = *schema {
                     let inner_schema = inner
diff --git a/lang/rust/src/error.rs b/lang/rust/src/error.rs
index f65ec72..d687eea 100644
--- a/lang/rust/src/error.rs
+++ b/lang/rust/src/error.rs
@@ -225,6 +225,9 @@ pub enum Error {
     #[error("Cannot convert u64 to usize: {1}")]
     ConvertU64ToUsize(#[source] std::num::TryFromIntError, u64),
 
+    #[error("Cannot convert u32 to usize: {1}")]
+    ConvertU32ToUsize(#[source] std::num::TryFromIntError, u32),
+
     #[error("Cannot convert i64 to usize: {1}")]
     ConvertI64ToUsize(#[source] std::num::TryFromIntError, i64),
 
diff --git a/lang/rust/src/ser.rs b/lang/rust/src/ser.rs
index 444ee20..5cff13e 100644
--- a/lang/rust/src/ser.rs
+++ b/lang/rust/src/ser.rs
@@ -142,7 +142,7 @@ impl<'b> ser::Serializer for &'b mut Serializer {
     }
 
     fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error> {
-        if v <= i32::max_value() as u32 {
+        if v <= i32::MAX as u32 {
             self.serialize_i32(v as i32)
         } else {
             self.serialize_i64(i64::from(v))
@@ -150,7 +150,7 @@ impl<'b> ser::Serializer for &'b mut Serializer {
     }
 
     fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error> {
-        if v <= i64::max_value() as u64 {
+        if v <= i64::MAX as u64 {
             self.serialize_i64(v as i64)
         } else {
             Err(ser::Error::custom("u64 is too large"))
@@ -203,7 +203,7 @@ impl<'b> ser::Serializer for &'b mut Serializer {
         index: u32,
         variant: &'static str,
     ) -> Result<Self::Ok, Self::Error> {
-        Ok(Value::Enum(index as i32, variant.to_string()))
+        Ok(Value::Enum(index, variant.to_string()))
     }
 
     fn serialize_newtype_struct<T: ?Sized>(
@@ -228,13 +228,10 @@ impl<'b> ser::Serializer for &'b mut Serializer {
         T: Serialize,
     {
         Ok(Value::Record(vec![
-            (
-                "type".to_owned(),
-                Value::Enum(index as i32, variant.to_owned()),
-            ),
+            ("type".to_owned(), Value::Enum(index, variant.to_owned())),
             (
                 "value".to_owned(),
-                Value::Union(index as i32, Box::new(value.serialize(self)?)),
+                Value::Union(index, Box::new(value.serialize(self)?)),
             ),
         ]))
     }
@@ -347,7 +344,7 @@ impl<'a> ser::SerializeSeq for SeqVariantSerializer<'a> {
         T: Serialize,
     {
         self.items.push(Value::Union(
-            self.index as i32,
+            self.index,
             Box::new(value.serialize(&mut Serializer::default())?),
         ));
         Ok(())
@@ -357,7 +354,7 @@ impl<'a> ser::SerializeSeq for SeqVariantSerializer<'a> {
         Ok(Value::Record(vec![
             (
                 "type".to_owned(),
-                Value::Enum(self.index as i32, self.variant.to_owned()),
+                Value::Enum(self.index, self.variant.to_owned()),
             ),
             ("value".to_owned(), Value::Array(self.items)),
         ]))
@@ -466,11 +463,11 @@ impl<'a> ser::SerializeStructVariant for StructVariantSerializer<'a> {
         Ok(Value::Record(vec![
             (
                 "type".to_owned(),
-                Value::Enum(self.index as i32, self.variant.to_owned()),
+                Value::Enum(self.index, self.variant.to_owned()),
             ),
             (
                 "value".to_owned(),
-                Value::Union(self.index as i32, Box::new(Value::Record(self.fields))),
+                Value::Union(self.index, Box::new(Value::Record(self.fields))),
             ),
         ]))
     }
diff --git a/lang/rust/src/types.rs b/lang/rust/src/types.rs
index 77472b0..85e7341 100644
--- a/lang/rust/src/types.rs
+++ b/lang/rust/src/types.rs
@@ -64,14 +64,14 @@ pub enum Value {
     /// of its corresponding schema.
     /// This allows schema-less encoding, as well as schema resolution while
     /// reading values.
-    Enum(i32, String),
+    Enum(u32, String),
     /// An `union` Avro value.
     ///
     /// A Union is represented by the value it holds and its position in the type list
     /// of its corresponding schema
     /// This allows schema-less encoding, as well as schema resolution while
     /// reading values.
-    Union(i32, Box<Value>),
+    Union(u32, Box<Value>),
     /// An `array` Avro value.
     Array(Vec<Value>),
     /// A `map` Avro value.
@@ -175,7 +175,7 @@ where
     fn from(value: Option<T>) -> Self {
         // FIXME: this is incorrect in case first type in union is not "none"
         Self::Union(
-            value.is_some() as i32,
+            value.is_some() as u32,
             Box::new(value.map_or_else(|| Self::Null, Into::into)),
         )
     }
@@ -684,7 +684,7 @@ impl Value {
     fn resolve_enum(self, symbols: &[String]) -> Result<Self, Error> {
         let validate_symbol = |symbol: String, symbols: &[String]| {
             if let Some(index) = symbols.iter().position(|item| item == &symbol) {
-                Ok(Value::Enum(index as i32, symbol))
+                Ok(Value::Enum(index as u32, symbol))
             } else {
                 Err(Error::GetEnumDefault {
                     symbol,
@@ -696,7 +696,7 @@ impl Value {
         match self {
             Value::Enum(raw_index, s) => {
                 let index = usize::try_from(raw_index)
-                    .map_err(|e| Error::ConvertI32ToUsize(e, raw_index))?;
+                    .map_err(|e| Error::ConvertU32ToUsize(e, raw_index))?;
                 if (0..=symbols.len()).contains(&index) {
                     validate_symbol(s, symbols)
                 } else {
@@ -721,7 +721,7 @@ impl Value {
         // Find the first match in the reader schema.
         // FIXME: this might be wrong when the union consists of multiple same records that have different names
         let (i, inner) = schema.find_schema(&v).ok_or(Error::FindUnionVariant)?;
-        Ok(Value::Union(i as i32, Box::new(v.resolve(inner)?)))
+        Ok(Value::Union(i as u32, Box::new(v.resolve(inner)?)))
     }
 
     fn resolve_array(self, schema: &Schema) -> Result<Self, Error> {