Skip to content

Commit

Permalink
Protect API backwards-compatibility around unknown logical type
Browse files Browse the repository at this point in the history
In case we also want to add support for extra logical type fields there, like is necessary for Decimal.
  • Loading branch information
Ten0 committed Mar 10, 2024
1 parent e9fbe05 commit 829c918
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 6 deletions.
2 changes: 1 addition & 1 deletion serde_avro_derive_macros/src/build_schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ pub(crate) fn schema_impl(input: SchemaDeriveInput) -> Result<TokenStream, Error
quote! { schema::LogicalType::#logical_type_ident_pascal }
} else {
quote! { schema::LogicalType::Unknown(
#logical_type_litstr.to_owned()
schema::UnknownLogicalType::new(#logical_type_litstr)
) }
};
if logical_type_str_pascal == "Decimal" {
Expand Down
26 changes: 22 additions & 4 deletions serde_avro_fast/src/schema/safe/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ pub enum LogicalType {
/// tuple, or to its raw representation [as defined by the specification](https://avro.apache.org/docs/current/specification/#duration)
/// if the deserializer is hinted this way ([`serde_bytes`](https://docs.rs/serde_bytes/latest/serde_bytes/)).
Duration,
/// An logical type that is not known or not handled in any particular way
/// A logical type that is not known or not handled in any particular way
/// by this library.
///
/// **You should not match on this variant.** (See below.)
Expand All @@ -387,7 +387,7 @@ pub enum LogicalType {
///
/// ```rust
/// # use serde_avro_fast::schema::LogicalType;
/// # let logical_type = LogicalType::Unknown("foo".to_string());
/// # let logical_type = LogicalType::Unknown(serde_avro_fast::schema::UnknownLogicalType::new("foo"));
/// match logical_type {
/// LogicalType::Uuid => { /* ... */ }
/// LogicalType::TimestampMillis => { /* ... */ }
Expand All @@ -402,7 +402,7 @@ pub enum LogicalType {
/// However, you may construct an instance of this variant if you need to
/// build a [`SchemaMut`] with a logical type that is not known to this
/// library.
Unknown(String),
Unknown(UnknownLogicalType),
}

/// Component of a [`SchemaMut`]
Expand All @@ -422,6 +422,24 @@ impl Decimal {
}
}

/// Component of a [`SchemaMut`]
///
/// Represents a logical type that is not known or not handled in any particular
/// way by this library.
#[derive(Clone, Debug)]
pub struct UnknownLogicalType {
pub logical_type_name: String,
_private: (),
}
impl UnknownLogicalType {
pub fn new(logical_type_name: impl Into<String>) -> Self {
Self {
logical_type_name: logical_type_name.into(),
_private: (),
}
}
}

impl LogicalType {
/// The name of the logical type
///
Expand All @@ -439,7 +457,7 @@ impl LogicalType {
LogicalType::TimestampMillis => "timestamp-millis",
LogicalType::TimestampMicros => "timestamp-micros",
LogicalType::Duration => "duration",
LogicalType::Unknown(name) => name,
LogicalType::Unknown(unknown_logical_type) => &unknown_logical_type.logical_type_name,
}
}
}
Expand Down
4 changes: 3 additions & 1 deletion serde_avro_fast/src/schema/safe/parsing/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,9 @@ impl<'a> SchemaConstructionState<'a> {
"timestamp-millis" => LogicalType::TimestampMillis,
"timestamp-micros" => LogicalType::TimestampMicros,
"duration" => LogicalType::Duration,
unknown => LogicalType::Unknown(unknown.to_owned()),
unknown => {
LogicalType::Unknown(UnknownLogicalType::new(unknown))
}
}
},
inner: self.register_node(
Expand Down

0 comments on commit 829c918

Please sign in to comment.