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 <[email protected]> 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> {
