1use std::marker::PhantomData;23use jrsonnet_gcmodule::Trace;45use super::PreparedFuncVal;6use crate::{7 function::FuncVal,8 typed::{FromUntyped, IntoUntyped, Typed},9 CallLocation, Result, Val,10};11use jrsonnet_types::{ComplexValType, ValType};1213#[derive(Debug, Trace, Clone)]14pub struct NativeFn<D: 'static>(pub(crate) PreparedFuncVal, PhantomData<D>);15macro_rules! impl_native_desc {16 ($i:expr; $($gen:ident)*) => {17 impl<$($gen,)* O> NativeFn<($($gen,)* O,)>18 where19 $($gen: Typed + IntoUntyped,)*20 O: Typed + FromUntyped,21 {22 #[allow(non_snake_case, clippy::too_many_arguments)]23 pub fn call(24 &self,25 $($gen: $gen,)*26 ) -> Result<O> {27 let val = self.0.call(28 CallLocation::native(),29 &[$(IntoUntyped::into_lazy_untyped($gen),)*],30 &[],31 )?;32 O::from_untyped(val)33 }34 }35 impl<$($gen,)* O> Typed for NativeFn<($($gen,)* O,)> {36 const TYPE: &'static ComplexValType = &ComplexValType::Simple(ValType::Func);37 }3839 impl<$($gen,)* O> FromUntyped for NativeFn<($($gen,)* O,)> {40 fn from_untyped(untyped: Val) -> Result<Self> {41 let func = FuncVal::from_untyped(untyped)?;42 Ok(Self(43 PreparedFuncVal::new(func, $i, &[])?,44 PhantomData,45 ))46 }47 }48 };49 ($i:expr; $($cur:ident)* @ $c:ident $($rest:ident)*) => {50 impl_native_desc!($i; $($cur)*);51 impl_native_desc!($i + 1; $($cur)* $c @ $($rest)*);52 };53 ($i:expr; $($cur:ident)* @) => {54 impl_native_desc!($i; $($cur)*);55 }56}5758impl_native_desc! {59 0; @ A B C D E F G H I J K L60}6162mod native_macro {63 #[macro_export]64 macro_rules! NativeFn {65 (($($t:ty),* $(,)?) -> $res:ty) => {66 NativeFn<($($t,)* $res)>67 }68 }69}70pub use crate::NativeFn;