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 pub name: BuiltinParamName,13 pub has_default: bool,14}151617pub trait Builtin: Trace {18 fn name(&self) -> &str;19 fn params(&self) -> &[BuiltinParam];20 fn call(&self, s: State, ctx: Context, loc: CallLocation, args: &dyn ArgsLike) -> Result<Val>;21}2223pub trait StaticBuiltin: Builtin + Send + Sync24where25 Self: 'static,26{27 28 29}3031#[derive(Trace)]32pub struct NativeCallback {33 pub(crate) params: Vec<BuiltinParam>,34 handler: TraceBox<dyn NativeCallbackHandler>,35}36impl NativeCallback {37 #[deprecated = "prefer using builtins directly, use this interface only for bindings"]38 pub fn new(params: Vec<BuiltinParam>, handler: TraceBox<dyn NativeCallbackHandler>) -> Self {39 Self { params, handler }40 }41}4243impl Builtin for NativeCallback {44 fn name(&self) -> &str {45 46 47 "<native>"48 }4950 fn params(&self) -> &[BuiltinParam] {51 &self.params52 }5354 fn call(&self, s: State, ctx: Context, _loc: CallLocation, args: &dyn ArgsLike) -> Result<Val> {55 let args = parse_builtin_call(s.clone(), ctx, &self.params, args, true)?;56 let mut out_args = Vec::with_capacity(self.params.len());57 for p in &self.params {58 out_args.push(args[&p.name].evaluate(s.clone())?);59 }60 self.handler.call(s, &out_args)61 }62}6364pub trait NativeCallbackHandler: Trace {65 fn call(&self, s: State, args: &[Val]) -> Result<Val>;66}