use derive_try_from_ref::TryFromRef;
use quote::ToTokens;
use crate::{
ast::{
host_ref_item::{HostRefStructItem, HostRefTraitImplItem},
ref_utils
},
ModuleImplIR
};
#[derive(syn_derive::ToTokens, TryFromRef)]
#[source(ModuleImplIR)]
#[err(syn::Error)]
pub struct FactoryHostRefItem {
struct_item: HostRefStructItem,
trait_impl_item: HostRefTraitImplItem,
impl_item: FactoryHostRefImplItem,
try_impl_item: FactoryHostRefTryImplItem
}
struct FactoryHostRefImplItem {
ref_ident: syn::Ident,
factory_fns: Vec<syn::ItemFn>
}
impl TryFrom<&'_ ModuleImplIR> for FactoryHostRefImplItem {
type Error = syn::Error;
fn try_from(module: &'_ ModuleImplIR) -> Result<Self, Self::Error> {
let fns = [module.factory_fn(), module.factory_upgrade_fn(), module.factory_batch_upgrade_fn()];
Ok(Self {
ref_ident: module.host_ref_ident()?,
factory_fns: fns.iter().map(|f| ref_utils::host_function_item(f, false)).collect()
})
}
}
impl ToTokens for FactoryHostRefImplItem {
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
let ref_ident = &self.ref_ident;
let factory_fns = &self.factory_fns;
tokens.extend(quote::quote! {
impl #ref_ident {
#(#factory_fns)*
}
});
}
}
struct FactoryHostRefTryImplItem {
ref_ident: syn::Ident,
factory_fns: Vec<syn::ItemFn>
}
impl TryFrom<&'_ ModuleImplIR> for FactoryHostRefTryImplItem {
type Error = syn::Error;
fn try_from(module: &'_ ModuleImplIR) -> Result<Self, Self::Error> {
let fns = [module.factory_fn(), module.factory_upgrade_fn(), module.factory_batch_upgrade_fn()];
Ok(Self {
ref_ident: module.host_ref_ident()?,
factory_fns: fns.iter().map(ref_utils::factory_try_function_item).collect()
})
}
}
impl ToTokens for FactoryHostRefTryImplItem {
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
let ref_ident = &self.ref_ident;
let factory_fns = &self.factory_fns;
tokens.extend(quote::quote! {
impl #ref_ident {
#(#factory_fns)*
}
});
}
}