1#![allow(clippy::type_complexity)]23use std::{path::Path, rc::Rc};45use gcmodule::Trace;67use crate::{8 error::Result,9 function::{parse_builtin_call, ArgsLike, Builtin, BuiltinParam, CallLocation},10 gc::TraceBox,11 Context, State, Val,12};1314#[derive(Trace)]15pub struct NativeCallback {16 pub(crate) params: Vec<BuiltinParam>,17 handler: TraceBox<dyn NativeCallbackHandler>,18}19impl NativeCallback {20 #[deprecated = "prefer using builtins directly, use this interface only for bindings"]21 pub fn new(params: Vec<BuiltinParam>, handler: TraceBox<dyn NativeCallbackHandler>) -> Self {22 Self { params, handler }23 }24}2526impl Builtin for NativeCallback {27 fn name(&self) -> &str {28 29 30 "<native>"31 }3233 fn params(&self) -> &[BuiltinParam] {34 &self.params35 }3637 fn call(&self, s: State, ctx: Context, loc: CallLocation, args: &dyn ArgsLike) -> Result<Val> {38 let args = parse_builtin_call(s.clone(), ctx, &self.params, args, true)?;39 let mut out_args = Vec::with_capacity(self.params.len());40 for p in &self.params {41 out_args.push(args[&p.name].evaluate(s.clone())?);42 }43 self.handler.call(s, loc.0.map(|l| l.0.clone()), &out_args)44 }45}4647pub trait NativeCallbackHandler: Trace {48 fn call(&self, s: State, from: Option<Rc<Path>>, args: &[Val]) -> Result<Val>;49}