use crate::{
core::{DecodeUntypedSlice, EncodeUntypedSlice, UntypedError, UntypedVal},
value::WithType,
Val,
};
use core::cmp;
#[derive(Debug)]
pub struct FuncInOut<'a> {
params_results: &'a mut [UntypedVal],
len_params: usize,
len_results: usize,
}
#[derive(Debug)]
pub struct FuncResults<'a> {
results: &'a mut [UntypedVal],
}
impl<'a> FuncResults<'a> {
fn new(results: &'a mut [UntypedVal]) -> Self {
Self { results }
}
pub fn encode_results<T>(self, values: T) -> FuncFinished
where
T: EncodeUntypedSlice,
{
UntypedVal::encode_slice::<T>(self.results, values)
.unwrap_or_else(|error| panic!("encountered unexpected invalid tuple length: {error}"));
FuncFinished {}
}
pub fn encode_results_from_slice(self, values: &[Val]) -> Result<FuncFinished, UntypedError> {
assert_eq!(self.results.len(), values.len());
self.results.iter_mut().zip(values).for_each(|(dst, src)| {
*dst = src.clone().into();
});
Ok(FuncFinished {})
}
}
#[derive(Debug)]
pub struct FuncFinished {}
impl<'a> FuncInOut<'a> {
pub fn new(
params_results: &'a mut [UntypedVal],
len_params: usize,
len_results: usize,
) -> Self {
assert_eq!(params_results.len(), cmp::max(len_params, len_results));
Self {
params_results,
len_params,
len_results,
}
}
fn params(&self) -> &[UntypedVal] {
&self.params_results[..self.len_params]
}
pub fn decode_params<T>(self) -> (T, FuncResults<'a>)
where
T: DecodeUntypedSlice,
{
let decoded = UntypedVal::decode_slice::<T>(self.params())
.unwrap_or_else(|error| panic!("encountered unexpected invalid tuple length: {error}"));
let results = self.into_func_results();
(decoded, results)
}
pub fn decode_params_into_slice(
self,
values: &mut [Val],
) -> Result<FuncResults<'a>, UntypedError> {
assert_eq!(self.params().len(), values.len());
self.params().iter().zip(values).for_each(|(src, dst)| {
*dst = src.with_type(dst.ty());
});
let results = self.into_func_results();
Ok(results)
}
fn into_func_results(self) -> FuncResults<'a> {
FuncResults::new(&mut self.params_results[..self.len_results])
}
}