sunflower/src/function/function_impl.rs

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