1use std::borrow::Cow;23use jrsonnet_gcmodule::Trace;45use super::{arglike::ArgsLike, parse::parse_builtin_call, CallLocation};6use crate::{error::Result, gc::TraceBox, Context, State, 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(28 &self,29 s: State,30 ctx: Context,31 loc: CallLocation<'_>,32 args: &dyn ArgsLike,33 ) -> Result<Val>;34}3536pub trait StaticBuiltin: Builtin + Send + Sync37where38 Self: 'static,39{40 41 42}4344#[derive(Trace)]45pub struct NativeCallback {46 pub(crate) params: Vec<BuiltinParam>,47 handler: TraceBox<dyn NativeCallbackHandler>,48}49impl NativeCallback {50 #[deprecated = "prefer using builtins directly, use this interface only for bindings"]51 pub fn new(52 params: Vec<Cow<'static, str>>,53 handler: TraceBox<dyn NativeCallbackHandler>,54 ) -> Self {55 Self {56 params: params57 .into_iter()58 .map(|n| BuiltinParam {59 name: Some(n),60 has_default: false,61 })62 .collect(),63 handler,64 }65 }66}6768impl Builtin for NativeCallback {69 fn name(&self) -> &str {70 71 72 "<native>"73 }7475 fn params(&self) -> &[BuiltinParam] {76 &self.params77 }7879 fn call(80 &self,81 s: State,82 ctx: Context,83 _loc: CallLocation<'_>,84 args: &dyn ArgsLike,85 ) -> Result<Val> {86 let args = parse_builtin_call(s.clone(), ctx, &self.params, args, true)?;87 let args = args88 .into_iter()89 .map(|a| a.expect("legacy natives have no default params"))90 .map(|a| a.evaluate(s.clone()))91 .collect::<Result<Vec<Val>>>()?;92 self.handler.call(s, &args)93 }94}9596pub trait NativeCallbackHandler: Trace {97 fn call(&self, s: State, args: &[Val]) -> Result<Val>;98}