Skip to content

Commit

Permalink
Fix direct lookup newtype schema generation (fixes #25)
Browse files Browse the repository at this point in the history
  • Loading branch information
Ten0 committed Oct 27, 2024
1 parent b5c6677 commit 84e751b
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ pub(super) struct FieldTypeAndInstantiationsBuilder<'t, 'm> {
pub(super) errors: &'m mut TokenStream,
pub(super) namespace: &'m Option<String>,
pub(super) expand_namespace_var: bool,
/// Whether at least one of the fields id directly looked up in the schema,
/// without necessarily inserting a new node. This is useful for newtype
/// struct serialization without logical type, whose type (and lookup)
/// should be directly the inner one
pub(super) has_direct_lookup: bool,
}

pub(super) enum FieldKind<'a> {
Expand Down Expand Up @@ -203,8 +208,10 @@ impl<'t> FieldTypeAndInstantiationsBuilder<'t, '_> {
}
}
}
override_field_instantiation
.unwrap_or_else(|| quote! { builder.find_or_build::<#ty>() })
override_field_instantiation.unwrap_or_else(|| {
self.has_direct_lookup = true;
quote! { builder.find_or_build::<#ty>() }
})
}
Some(logical_type_litstr) => {
let logical_type_str_raw = logical_type_litstr.value();
Expand Down
40 changes: 26 additions & 14 deletions serde_avro_derive_macros/src/build_schema/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ pub(crate) fn schema_impl(input: SchemaDeriveInput) -> Result<TokenStream, Error
errors: &mut errors,
namespace: &input.namespace,
expand_namespace_var: false,
has_direct_lookup: false,
};

let type_lookup: syn::Type;
Expand All @@ -125,20 +126,31 @@ pub(crate) fn schema_impl(input: SchemaDeriveInput) -> Result<TokenStream, Error
struct_name: name_ident,
},
);
let namespace_var = field_types_and_instantiations
.expand_namespace_var
.then(lazy_compute_namespace);
(type_lookup, type_lookup_decl, _) = type_lookup::build_type_lookup(
type_ident,
&generics,
None,
std::slice::from_ref(&field_type),
);
quote! {
let n_nodes = builder.nodes.len();
#namespace_var
let new_node_key = #field_instantiation;
assert_eq!(n_nodes, new_node_key.idx());
if field_types_and_instantiations.has_direct_lookup {
// This single field is a direct lookup (no logical type,
// etc), so this is the special case we need to just
// expand into forwarding.
type_lookup = parse_quote! { <#field_type as serde_avro_derive::BuildSchema>::TypeLookup };
type_lookup_decl = None;
quote! {
<#field_type as serde_avro_derive::BuildSchema>::append_schema(builder);
}
} else {
let namespace_var = field_types_and_instantiations
.expand_namespace_var
.then(lazy_compute_namespace);
(type_lookup, type_lookup_decl, _) = type_lookup::build_type_lookup(
type_ident,
&generics,
None,
std::slice::from_ref(&field_type),
);
quote! {
let n_nodes = builder.nodes.len();
#namespace_var
let new_node_key = #field_instantiation;
assert_eq!(n_nodes, new_node_key.idx());
}
}
} else {
// named struct
Expand Down
1 change: 1 addition & 0 deletions serde_avro_derive_macros/src/build_schema/type_lookup.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use super::*;

/// Returned boolean is `has_non_lifetime_generics`
pub(super) fn build_type_lookup(
type_ident: &syn::Ident,
generics: &syn::Generics,
Expand Down

0 comments on commit 84e751b

Please sign in to comment.