use crate::utils::name_expr;
use proc_macro2::{Ident, TokenStream};
use quote::quote;
use syn::Generics;
pub struct Implementation {
ident: Ident,
generics: Generics,
schema_expr: TokenStream,
record_fields_expr: TokenStream,
field_default_expr: TokenStream,
}
impl Implementation {
#[expect(
clippy::needless_pass_by_value,
reason = "Makes it match the `unnamed` variant"
)]
pub fn named(
ident: Ident,
generics: Generics,
name: &str,
schema_expr: TokenStream,
record_fields_expr: Option<TokenStream>,
field_default_expr: Option<TokenStream>,
) -> Implementation {
let name_expr = name_expr(name);
let schema_expr = quote! {
let name = #name_expr;
if named_schemas.contains(&name) {
::apache_avro::schema::Schema::Ref{name}
} else {
let enclosing_namespace = name.namespace();
named_schemas.insert(name.clone());
#schema_expr
}
};
Self::unnamed(
ident,
generics,
schema_expr,
record_fields_expr,
field_default_expr,
)
}
pub fn unnamed(
ident: Ident,
generics: Generics,
schema_expr: TokenStream,
record_fields_expr: Option<TokenStream>,
field_default_expr: Option<TokenStream>,
) -> Implementation {
Self {
ident,
generics,
schema_expr,
record_fields_expr: record_fields_expr
.unwrap_or_else(|| quote! { ::std::option::Option::None }),
field_default_expr: field_default_expr
.unwrap_or_else(|| quote! { ::std::option::Option::None }),
}
}
pub fn into_token_stream(self) -> TokenStream {
let (impl_generics, ty_generics, where_clause) = self.generics.split_for_impl();
let ident = self.ident;
let schema_expr = self.schema_expr;
let record_fields_expr = self.record_fields_expr;
let field_default_expr = self.field_default_expr;
quote! {
#[automatically_derived]
impl #impl_generics ::apache_avro::AvroSchemaComponent for #ident #ty_generics #where_clause {
fn get_schema_in_ctxt(named_schemas: &mut ::std::collections::HashSet<::apache_avro::schema::Name>, enclosing_namespace: ::apache_avro::schema::NamespaceRef) -> ::apache_avro::schema::Schema {
#schema_expr
}
fn get_record_fields_in_ctxt(named_schemas: &mut ::std::collections::HashSet<::apache_avro::schema::Name>, enclosing_namespace: ::apache_avro::schema::NamespaceRef) -> ::std::option::Option<::std::vec::Vec<::apache_avro::schema::RecordField>> {
#record_fields_expr
}
fn field_default() -> ::std::option::Option<::serde_json::Value> {
#field_default_expr
}
}
}
}
}