1use std::marker::PhantomData;23use jrsonnet_gcmodule::Trace;45use super::PreparedFuncVal;6use crate::{bail, function::FuncVal, typed::Typed, CallLocation, Result, Val};7use jrsonnet_types::{ComplexValType, ValType};89#[derive(Debug, Trace, Clone)]10pub struct NativeFn<D: 'static>(pub(crate) PreparedFuncVal, PhantomData<D>);11macro_rules! impl_native_desc {12 ($i:expr; $($gen:ident)*) => {13 impl<$($gen,)* O> NativeFn<($($gen,)* O,)>14 where15 $($gen: Typed,)*16 O: Typed,17 {18 #[allow(non_snake_case, clippy::too_many_arguments)]19 pub fn call(20 &self,21 $($gen: $gen,)*22 ) -> Result<O> {23 let val = self.0.call(24 CallLocation::native(),25 &[$(Typed::into_lazy_untyped($gen),)*],26 &[],27 )?;28 O::from_untyped(val)29 }30 }31 impl<$($gen,)* O> Typed for NativeFn<($($gen,)* O,)> {32 const TYPE: &'static ComplexValType = &ComplexValType::Simple(ValType::Func);3334 fn into_untyped(_typed: Self) -> Result<Val> {35 bail!("can only convert functions from jsonnet to native")36 }3738 fn from_untyped(untyped: Val) -> Result<Self> {39 let func = FuncVal::from_untyped(untyped)?;40 Ok(Self(41 PreparedFuncVal::new(func, $i, &[])?,42 PhantomData,43 ))44 }45 }46 };47 ($i:expr; $($cur:ident)* @ $c:ident $($rest:ident)*) => {48 impl_native_desc!($i; $($cur)*);49 impl_native_desc!($i + 1; $($cur)* $c @ $($rest)*);50 };51 ($i:expr; $($cur:ident)* @) => {52 impl_native_desc!($i; $($cur)*);53 }54}5556impl_native_desc! {57 0; @ A B C D E F G H I J K L58}5960mod native_macro {61 #[macro_export]62 macro_rules! NativeFn {63 (($($t:ty),* $(,)?) -> $res:ty) => {64 NativeFn<($($t,)* $res)>65 }66 }67}68pub use crate::NativeFn;