use super::{Env, FromValue, NativeFunction, Value}; macro_rules! impl_function { ( $($ty:ident),* $(,)? ) => { #[allow(non_snake_case, unused_variables, unused_mut, unused_assignments)] impl NativeFunction<((),(),$($ty,)*)> for F where F: Fn($($ty,)*) -> R, R: Into, $($ty: FromValue,)* { fn native_execute(&self, _: &Env, args: &[Value]) -> Result { 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 NativeFunction<((),(),(), $($ty,)*)> for F where F: Fn(&Env, $($ty,)*) -> R, R: Into, $($ty: FromValue,)* { fn native_execute(&self, env: &Env, args: &[Value]) -> Result { 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 NativeFunction<(Z,$($ty,)*)> for F where F: Fn(&Z, $(&$ty,)*) -> R, R: Into, Z: FromValue, $($ty: FromValue,)* { fn native_execute(&self, _: &Env, args: &[Value]) -> Result { 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.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 NativeFunction<((), Z, $($ty,)*)> for F where F: Fn(&Env, &Z, $(&$ty,)*) -> R, R: Into, Z: FromValue, $($ty: FromValue,)* { fn native_execute(&self, env: &Env, args: &[Value]) -> Result { 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.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);