use proc_macro::TokenStream;
use proc_macro2::Span;
use quote::quote;
use syn::{Ident, ItemTrait, TraitBound, punctuated::Punctuated, token::Plus};
pub fn generate(
product_trait: ItemTrait,
product_bounds: Punctuated<TraitBound, Plus>,
) -> TokenStream {
let product_vis = &product_trait.vis;
let product_ident = &product_trait.ident;
let factory_ident = Ident::new(&format!("{product_ident}Factory"), Span::call_site());
let bounds_iter = product_bounds.iter();
let product_type = quote! { dyn #product_ident #( + #bounds_iter )* };
quote! {
#product_trait
#product_vis struct #factory_ident;
impl #factory_ident {
#[inline]
pub fn create(
id: &str,
strategy: rust_patterns::FactoryFallback,
) -> std::result::Result<(&str, Box<#product_type>), rust_patterns::FactoryError> {
use std::sync::LazyLock;
use rust_patterns::{FactoryRegistry, SimpleFactory};
static FACTORY: LazyLock<SimpleFactory<#product_type>> =
LazyLock::new(FactoryRegistry::simple_factory);
FACTORY.create(id, strategy)
}
}
}
.into()
}