use crate::ModuleImplIR;
use proc_macro2::TokenStream;
use syn::parse_quote;
#[derive(syn_derive::ToTokens)]
pub struct ContractItem {
code: TokenStream
}
impl TryFrom<&'_ ModuleImplIR> for ContractItem {
type Error = syn::Error;
fn try_from(module: &'_ ModuleImplIR) -> Result<Self, Self::Error> {
let module_ident = module.module_ident()?;
let host_ref = module.host_ref_ident()?;
let contract_ref = module.contract_ref_ident()?;
let has_constructor_args = module
.constructor()
.map(|c| c.has_args())
.unwrap_or_default();
let init_args: syn::Path = match has_constructor_args {
true => module.init_args_ident()?.into(),
false => parse_quote!(odra::host::NoArgs)
};
let has_upgrade_args = module.upgrader().map(|c| c.has_args()).unwrap_or_default();
let upgrade_args: syn::Path = match has_upgrade_args {
true => module.upgrade_args_ident()?.into(),
false => parse_quote!(odra::host::NoArgs)
};
Ok(Self {
code: quote::quote! {
impl odra::OdraContract for #module_ident {
#[cfg(not(target_arch = "wasm32"))]
type HostRef = #host_ref;
type ContractRef = #contract_ref;
#[cfg(not(target_arch = "wasm32"))]
type InitArgs = #init_args;
#[cfg(not(target_arch = "wasm32"))]
type UpgradeArgs = #upgrade_args;
}
}
})
}
}
#[cfg(test)]
mod test {
use super::*;
use crate::test_utils;
#[test]
fn test_contract_item() {
let module = test_utils::mock::module_impl();
let item = ContractItem::try_from(&module).unwrap();
let expected = quote::quote! {
impl odra::OdraContract for Erc20 {
#[cfg(not(target_arch = "wasm32"))]
type HostRef = Erc20HostRef;
type ContractRef = Erc20ContractRef;
#[cfg(not(target_arch = "wasm32"))]
type InitArgs = Erc20InitArgs;
#[cfg(not(target_arch = "wasm32"))]
type UpgradeArgs = Erc20UpgradeArgs;
}
};
test_utils::assert_eq(item, expected);
}
}