use super::{Func, into_func::WasmTyList};
use crate::{
AsContext,
AsContextMut,
Error,
TypedResumableCall,
engine::{LiftFromCellsByValue, LoadByVal, LowerToCells},
};
use core::{fmt, fmt::Debug, marker::PhantomData};
#[repr(transparent)]
pub struct TypedFunc<Params, Results> {
signature: PhantomData<fn(Params) -> Results>,
func: Func,
}
impl<Params, Results> Debug for TypedFunc<Params, Results> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("TypedFunc")
.field("signature", &self.signature)
.field("func", &self.func)
.finish()
}
}
impl<Params, Results> Copy for TypedFunc<Params, Results> {}
impl<Params, Results> Clone for TypedFunc<Params, Results> {
fn clone(&self) -> TypedFunc<Params, Results> {
*self
}
}
impl<Params, Results> TypedFunc<Params, Results> {
pub fn func(&self) -> &Func {
&self.func
}
}
impl<Params, Results> TypedFunc<Params, Results>
where
Params: WasmParams,
Results: WasmResults,
{
pub(crate) fn new(ctx: impl AsContext, func: Func) -> Result<Self, Error> {
let func_type = func.ty(&ctx);
let (actual_params, actual_results) = (
<Params as WasmTyList>::types(),
<Results as WasmTyList>::types(),
);
func_type.match_params(actual_params.as_ref())?;
func_type.match_results(actual_results.as_ref())?;
Ok(Self {
signature: PhantomData,
func,
})
}
pub fn call(&self, mut ctx: impl AsContextMut, params: Params) -> Result<Results, Error> {
ctx.as_context().store.engine().clone().execute_func(
ctx.as_context_mut(),
&self.func,
params,
<LoadByVal<Results>>::default(),
)
}
pub fn call_resumable(
&self,
mut ctx: impl AsContextMut,
params: Params,
) -> Result<TypedResumableCall<Results>, Error> {
ctx.as_context()
.store
.engine()
.clone()
.execute_func_resumable(
ctx.as_context_mut(),
&self.func,
params,
<LoadByVal<Results>>::default(),
)
.map(TypedResumableCall::new)
}
}
pub trait WasmParams: WasmTyList + LowerToCells {}
impl<T> WasmParams for T where T: WasmTyList + LowerToCells {}
pub trait WasmResults: WasmTyList + LiftFromCellsByValue {}
impl<T> WasmResults for T where T: WasmTyList + LiftFromCellsByValue {}