This is an automated email from the ASF dual-hosted git repository. kriskras99 pushed a commit to branch fix/ref_option in repository https://gitbox.apache.org/repos/asf/avro-rs.git
commit e07d7a88da07fe7ed8e3475942ddee930e439ce8 Author: Kriskras99 <[email protected]> AuthorDate: Sun Mar 1 10:50:53 2026 +0100 fix: Enable `ref_option` lint and fix the warnings it generates --- .clippy.toml | 1 + Cargo.toml | 1 + avro/src/bytes.rs | 3 +++ avro/src/schema/parser.rs | 2 +- avro/src/schema/record/field.rs | 8 ++++---- avro/src/schema/union.rs | 6 +++--- avro/src/serde/derive.rs | 40 +++++++++++++++++++++++++++++++-------- avro/src/serde/with.rs | 3 +++ avro/src/types.rs | 31 +++++++++++++++++------------- avro_derive/src/attributes/mod.rs | 4 ++-- 10 files changed, 68 insertions(+), 31 deletions(-) diff --git a/.clippy.toml b/.clippy.toml new file mode 100644 index 0000000..87e1f23 --- /dev/null +++ b/.clippy.toml @@ -0,0 +1 @@ +avoid-breaking-exported-api = false \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index 9ca5059..fcba48e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -56,6 +56,7 @@ opt-level = "s" clippy.all = { level = "warn", priority = -1 } clippy.too_long_first_doc_paragraph = "warn" clippy.doc_markdown = "warn" +clippy.ref_option = "warn" # TODO: Needs more work #clippy.missing_errors_doc = "warn" #clippy.missing_panics_doc = "warn" diff --git a/avro/src/bytes.rs b/avro/src/bytes.rs index 341b01d..869bbfc 100644 --- a/avro/src/bytes.rs +++ b/avro/src/bytes.rs @@ -69,6 +69,7 @@ pub mod serde_avro_bytes_opt { since = "0.22.0", note = "Use `apache_avro::serde::bytes_opt::serialize` instead" )] + #[expect(clippy::ref_option, reason = "Required by the Serde API")] pub fn serialize<S, B>(bytes: &Option<B>, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer, @@ -135,6 +136,7 @@ pub mod serde_avro_fixed_opt { since = "0.22.0", note = "Use `apache_avro::serde::fixed_opt::serialize` instead" )] + #[expect(clippy::ref_option, reason = "Required by the Serde API")] pub fn serialize<S, B>(bytes: &Option<B>, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer, @@ -201,6 +203,7 @@ pub mod serde_avro_slice_opt { since = "0.22.0", note = "Use `apache_avro::serde::slice_opt::serialize` instead" )] + #[expect(clippy::ref_option, reason = "Required by the Serde API")] pub fn serialize<S, B>(bytes: &Option<B>, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer, diff --git a/avro/src/schema/parser.rs b/avro/src/schema/parser.rs index 0f89018..f0a234d 100644 --- a/avro/src/schema/parser.rs +++ b/avro/src/schema/parser.rs @@ -658,7 +658,7 @@ impl Parser { if let Some(ref value) = default { let resolved = types::Value::from(value.clone()) - .resolve_enum(&symbols, &Some(value.to_string()), &None) + .resolve_enum(&symbols, Some(value.as_str()), None) .is_ok(); if !resolved { return Err(Details::GetEnumDefault { diff --git a/avro/src/schema/record/field.rs b/avro/src/schema/record/field.rs index 11326e1..f8dce53 100644 --- a/avro/src/schema/record/field.rs +++ b/avro/src/schema/record/field.rs @@ -106,7 +106,7 @@ impl RecordField { name, &enclosing_record.fullname(None), parser.get_parsed_schemas(), - &default, + default.as_ref(), )?; let aliases = field @@ -137,7 +137,7 @@ impl RecordField { field_name: &str, record_name: &str, names: &Names, - default: &Option<Value>, + default: Option<&Value>, ) -> AvroResult<()> { if let Some(value) = default { let avro_value = types::Value::try_from(value.clone())?; @@ -147,7 +147,7 @@ impl RecordField { let resolved = schemas.iter().any(|schema| { avro_value .to_owned() - .resolve_internal(schema, names, schema.namespace(), &None) + .resolve_internal(schema, names, schema.namespace(), None) .is_ok() }); @@ -165,7 +165,7 @@ impl RecordField { } _ => { let resolved = avro_value - .resolve_internal(field_schema, names, field_schema.namespace(), &None) + .resolve_internal(field_schema, names, field_schema.namespace(), None) .is_ok(); if !resolved { diff --git a/avro/src/schema/union.rs b/avro/src/schema/union.rs index 31affe7..24edfee 100644 --- a/avro/src/schema/union.rs +++ b/avro/src/schema/union.rs @@ -106,7 +106,7 @@ impl UnionSchema { // TODO: Do this without the clone value .clone() - .resolve_internal(schema, known_schemata, namespace, &None) + .resolve_internal(schema, known_schemata, namespace, None) .ok() .map(|_| (index, schema)) } else { @@ -130,7 +130,7 @@ impl UnionSchema { // TODO: Do this without the clone value .clone() - .resolve_internal(schema, known_schemata, namespace, &None) + .resolve_internal(schema, known_schemata, namespace, None) .is_ok() }) }); @@ -148,7 +148,7 @@ impl UnionSchema { // TODO: Do this without the clone value .clone() - .resolve_internal(schema, known_schemata, namespace, &None) + .resolve_internal(schema, known_schemata, namespace, None) .is_ok() }) } diff --git a/avro/src/serde/derive.rs b/avro/src/serde/derive.rs index d979962..770d11b 100644 --- a/avro/src/serde/derive.rs +++ b/avro/src/serde/derive.rs @@ -572,7 +572,10 @@ where Schema::array(T::get_schema_in_ctxt(named_schemas, enclosing_namespace)).build() } - fn get_record_fields_in_ctxt(_: &mut HashSet<Name>, _: NamespaceRef) -> Option<Vec<RecordField>> { + fn get_record_fields_in_ctxt( + _: &mut HashSet<Name>, + _: NamespaceRef, + ) -> Option<Vec<RecordField>> { None } } @@ -588,7 +591,10 @@ where Schema::map(T::get_schema_in_ctxt(named_schemas, enclosing_namespace)).build() } - fn get_record_fields_in_ctxt(_: &mut HashSet<Name>, _: NamespaceRef) -> Option<Vec<RecordField>> { + fn get_record_fields_in_ctxt( + _: &mut HashSet<Name>, + _: NamespaceRef, + ) -> Option<Vec<RecordField>> { None } } @@ -611,7 +617,10 @@ where ) } - fn get_record_fields_in_ctxt(_: &mut HashSet<Name>, _: NamespaceRef) -> Option<Vec<RecordField>> { + fn get_record_fields_in_ctxt( + _: &mut HashSet<Name>, + _: NamespaceRef, + ) -> Option<Vec<RecordField>> { None } @@ -645,7 +654,10 @@ impl AvroSchemaComponent for core::time::Duration { } } - fn get_record_fields_in_ctxt(_: &mut HashSet<Name>, _: NamespaceRef) -> Option<Vec<RecordField>> { + fn get_record_fields_in_ctxt( + _: &mut HashSet<Name>, + _: NamespaceRef, + ) -> Option<Vec<RecordField>> { None } } @@ -675,7 +687,10 @@ impl AvroSchemaComponent for uuid::Uuid { } } - fn get_record_fields_in_ctxt(_: &mut HashSet<Name>, _: NamespaceRef) -> Option<Vec<RecordField>> { + fn get_record_fields_in_ctxt( + _: &mut HashSet<Name>, + _: NamespaceRef, + ) -> Option<Vec<RecordField>> { None } } @@ -703,7 +718,10 @@ impl AvroSchemaComponent for u64 { } } - fn get_record_fields_in_ctxt(_: &mut HashSet<Name>, _: NamespaceRef) -> Option<Vec<RecordField>> { + fn get_record_fields_in_ctxt( + _: &mut HashSet<Name>, + _: NamespaceRef, + ) -> Option<Vec<RecordField>> { None } } @@ -731,7 +749,10 @@ impl AvroSchemaComponent for u128 { } } - fn get_record_fields_in_ctxt(_: &mut HashSet<Name>, _: NamespaceRef) -> Option<Vec<RecordField>> { + fn get_record_fields_in_ctxt( + _: &mut HashSet<Name>, + _: NamespaceRef, + ) -> Option<Vec<RecordField>> { None } } @@ -759,7 +780,10 @@ impl AvroSchemaComponent for i128 { } } - fn get_record_fields_in_ctxt(_: &mut HashSet<Name>, _: NamespaceRef) -> Option<Vec<RecordField>> { + fn get_record_fields_in_ctxt( + _: &mut HashSet<Name>, + _: NamespaceRef, + ) -> Option<Vec<RecordField>> { None } } diff --git a/avro/src/serde/with.rs b/avro/src/serde/with.rs index 29744e1..d6a2a8b 100644 --- a/avro/src/serde/with.rs +++ b/avro/src/serde/with.rs @@ -186,6 +186,7 @@ pub mod bytes_opt { None } + #[expect(clippy::ref_option, reason = "Required by the Serde API")] pub fn serialize<S, B>(bytes: &Option<B>, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer, @@ -343,6 +344,7 @@ pub mod fixed_opt { None } + #[expect(clippy::ref_option, reason = "Required by the Serde API")] pub fn serialize<S, B>(bytes: &Option<B>, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer, @@ -484,6 +486,7 @@ pub mod slice_opt { None } + #[expect(clippy::ref_option, reason = "Required by the Serde API")] pub fn serialize<S, B>(bytes: &Option<B>, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer, diff --git a/avro/src/types.rs b/avro/src/types.rs index 90ea2b0..f7f0e55 100644 --- a/avro/src/types.rs +++ b/avro/src/types.rs @@ -674,7 +674,7 @@ impl Value { } else { ResolvedSchema::try_from(schemata)? }; - self.resolve_internal(schema, rs.get_names(), enclosing_namespace, &None) + self.resolve_internal(schema, rs.get_names(), enclosing_namespace, None) } pub(crate) fn resolve_internal<S: Borrow<Schema> + Debug>( @@ -682,7 +682,7 @@ impl Value { schema: &Schema, names: &HashMap<Name, S>, enclosing_namespace: NamespaceRef, - field_default: &Option<JsonValue>, + field_default: Option<&JsonValue>, ) -> AvroResult<Self> { // Check if this schema is a union, and if the reader schema is not. if SchemaKind::from(&self) == SchemaKind::Union @@ -721,7 +721,7 @@ impl Value { } Schema::Enum(EnumSchema { symbols, default, .. - }) => self.resolve_enum(symbols, default, field_default), + }) => self.resolve_enum(symbols, default.as_deref(), field_default), Schema::Array(inner) => self.resolve_array(&inner.items, names, enclosing_namespace), Schema::Map(inner) => self.resolve_map(&inner.types, names, enclosing_namespace), Schema::Record(RecordSchema { fields, .. }) => { @@ -1039,8 +1039,8 @@ impl Value { pub(crate) fn resolve_enum( self, symbols: &[String], - enum_default: &Option<String>, - _field_default: &Option<JsonValue>, + enum_default: Option<&str>, + _field_default: Option<&JsonValue>, ) -> Result<Self, Error> { let validate_symbol = |symbol: String, symbols: &[String]| { if let Some(index) = symbols.iter().position(|item| item == &symbol) { @@ -1049,7 +1049,7 @@ impl Value { match enum_default { Some(default) => { if let Some(index) = symbols.iter().position(|item| item == default) { - Ok(Value::Enum(index as u32, default.clone())) + Ok(Value::Enum(index as u32, default.to_string())) } else { Err(Details::GetEnumDefault { symbol, @@ -1079,7 +1079,7 @@ impl Value { schema: &UnionSchema, names: &HashMap<Name, S>, enclosing_namespace: NamespaceRef, - field_default: &Option<JsonValue>, + field_default: Option<&JsonValue>, ) -> Result<Self, Error> { let v = match self { // Both are unions case. @@ -1110,7 +1110,7 @@ impl Value { Value::Array(items) => Ok(Value::Array( items .into_iter() - .map(|item| item.resolve_internal(schema, names, enclosing_namespace, &None)) + .map(|item| item.resolve_internal(schema, names, enclosing_namespace, None)) .collect::<Result<_, _>>()?, )), other => Err(Details::GetArray { @@ -1133,7 +1133,7 @@ impl Value { .into_iter() .map(|(key, value)| { value - .resolve_internal(schema, names, enclosing_namespace, &None) + .resolve_internal(schema, names, enclosing_namespace, None) .map(|value| (key, value)) }) .collect::<Result<_, _>>()?, @@ -1177,8 +1177,8 @@ impl Value { .. }) => Value::try_from(value.clone())?.resolve_enum( symbols, - default, - &field.default.clone(), + default.as_deref(), + field.default.as_ref(), )?, Schema::Union(ref union_schema) => { let first = &union_schema.variants()[0]; @@ -1193,7 +1193,7 @@ impl Value { first, names, enclosing_namespace, - &field.default, + field.default.as_ref(), )?, ), ), @@ -1207,7 +1207,12 @@ impl Value { }, }; value - .resolve_internal(&field.schema, names, enclosing_namespace, &field.default) + .resolve_internal( + &field.schema, + names, + enclosing_namespace, + field.default.as_ref(), + ) .map(|value| (field.name.clone(), value)) }) .collect::<Result<Vec<_>, _>>()?; diff --git a/avro_derive/src/attributes/mod.rs b/avro_derive/src/attributes/mod.rs index 27c1cbc..cfdae4f 100644 --- a/avro_derive/src/attributes/mod.rs +++ b/avro_derive/src/attributes/mod.rs @@ -202,7 +202,7 @@ pub enum With { impl With { fn from_avro_and_serde( avro: &avro::With, - serde: &Option<String>, + serde: Option<&str>, span: Span, ) -> Result<Self, syn::Error> { match &avro { @@ -327,7 +327,7 @@ impl FieldOptions { "`#[serde(skip_serializing)]` and `#[serde(skip_serializing_if)]` are incompatible with `#[avro(default = false)]`" )); } - let with = match With::from_avro_and_serde(&avro.with, &serde.with, span) { + let with = match With::from_avro_and_serde(&avro.with, serde.with.as_deref(), span) { Ok(with) => with, Err(error) => { errors.push(error);
