1use std::borrow::Cow;23use jrsonnet_gcmodule::Trace;45use super::{arglike::ArgsLike, parse::parse_builtin_call, CallLocation};6use crate::{error::Result, gc::TraceBox, Context, Val};78pub type BuiltinParamName = Cow<'static, str>;910#[derive(Clone, Trace)]11pub struct BuiltinParam {12 13 pub name: Option<BuiltinParamName>,14 15 pub has_default: bool,16}1718192021pub trait Builtin: Trace {22 23 fn name(&self) -> &str;24 25 fn params(&self) -> &[BuiltinParam];26 27 fn call(&self, ctx: Context, loc: CallLocation<'_>, args: &dyn ArgsLike) -> Result<Val>;28}2930pub trait StaticBuiltin: Builtin + Send + Sync31where32 Self: 'static,33{34 35 36}3738#[derive(Trace)]39pub struct NativeCallback {40 pub(crate) params: Vec<BuiltinParam>,41 handler: TraceBox<dyn NativeCallbackHandler>,42}43impl NativeCallback {44 #[deprecated = "prefer using builtins directly, use this interface only for bindings"]45 pub fn new(46 params: Vec<Cow<'static, str>>,47 handler: TraceBox<dyn NativeCallbackHandler>,48 ) -> Self {49 Self {50 params: params51 .into_iter()52 .map(|n| BuiltinParam {53 name: Some(n),54 has_default: false,55 })56 .collect(),57 handler,58 }59 }60}6162impl Builtin for NativeCallback {63 fn name(&self) -> &str {64 65 66 "<native>"67 }6869 fn params(&self) -> &[BuiltinParam] {70 &self.params71 }7273 fn call(&self, ctx: Context, _loc: CallLocation<'_>, args: &dyn ArgsLike) -> Result<Val> {74 let args = parse_builtin_call(ctx, &self.params, args, true)?;75 let args = args76 .into_iter()77 .map(|a| a.expect("legacy natives have no default params"))78 .map(|a| a.evaluate())79 .collect::<Result<Vec<Val>>>()?;80 self.handler.call(&args)81 }82}8384pub trait NativeCallbackHandler: Trace {85 fn call(&self, args: &[Val]) -> Result<Val>;86}