sunflower/src/function/function_impl.rs

68 lines
2.5 KiB
Rust

use super::{Env, FromValue, NativeFunction, Value};
macro_rules! impl_function {
( $($ty:ident),* $(,)? ) => {
#[allow(non_snake_case, unused_variables, unused_mut, unused_assignments)]
impl<F,R,$($ty,)*> NativeFunction<($($ty,)*)> for F
where
F: Fn($(&$ty,)*) -> R,
R: Into<Value>,
$($ty: FromValue,)*
{
fn native_execute(&self, _: &Env, args: &[Value]) -> Result<Value, String> {
let mut args = args.iter();
let total_count = {
let mut count = 0;
$(
let _: Option<$ty> = None;
count += 1;
)*
count
};
let mut count = 0;
$(
let arg = args.next()
.ok_or_else(|| format!("method expected {} parameters, but parameter {} was missing", total_count, count))?;
let $ty = $ty::from_value(arg)
.ok_or_else(|| format!("Parameter {} was not of type {}, it was {}", count, std::any::type_name::<$ty>(), arg.value_kind()))?;
count += 1;
)*
Ok(self($($ty,)*).into())
}
}
#[allow(non_snake_case, unused_variables, unused_mut, unused_assignments)]
impl<F,R,$($ty,)*> NativeFunction<((), $($ty,)*)> for F
where
F: Fn(&Env, $(&$ty,)*) -> R,
R: Into<Value>,
$($ty: FromValue,)*
{
fn native_execute(&self, env: &Env, args: &[Value]) -> Result<Value, String> {
let mut args = args.iter();
let total_count = {
let mut count = 0;
$(
let _: Option<$ty> = None;
count += 1;
)*
count
};
let mut count = 0;
$(
let arg = args.next()
.ok_or_else(|| format!("method expected {} parameters, but parameter {} was missing", total_count, count))?;
let $ty = $ty::from_value(arg)
.ok_or_else(|| format!("Parameter {} was not of type {}, it was {}", count, std::any::type_name::<$ty>(), arg.value_kind()))?;
count += 1;
)*
Ok(self(env, $($ty,)*).into())
}
}
};
}
crate::macros::for_each_tuple!(impl_function);