git.delta.rocks / jrsonnet / refs/commits / 76b0db1d8913

difftreelog

feat builtin downcasting

Yaroslav Bolyukin2023-02-16parent: #5acdbdb.patch.diff
in: master

2 files changed

modifiedcrates/jrsonnet-evaluator/src/function/builtin.rsdiffbeforeafterboth
before · crates/jrsonnet-evaluator/src/function/builtin.rs
1use std::borrow::Cow;23use jrsonnet_gcmodule::Trace;45use super::{arglike::ArgsLike, parse::parse_builtin_call, CallLocation};6use crate::{error::Result, gc::TraceBox, tb, Context, Val};78pub type BuiltinParamName = Cow<'static, str>;910#[derive(Clone, Trace)]11pub struct BuiltinParam {12	/// Parameter name for named call parsing13	pub name: Option<BuiltinParamName>,14	/// Is implementation allowed to return empty value15	pub has_default: bool,16}1718/// Description of function defined by native code19///20/// Prefer to use #[builtin] macro, instead of manual implementation of this trait21pub trait Builtin: Trace {22	/// Function name to be used in stack traces23	fn name(&self) -> &str;24	/// Parameter names for named calls25	fn params(&self) -> &[BuiltinParam];26	/// Call the builtin27	fn call(&self, ctx: Context, loc: CallLocation<'_>, args: &dyn ArgsLike) -> Result<Val>;28}2930pub trait StaticBuiltin: Builtin + Send + Sync31where32	Self: 'static,33{34	// In impl, to make it object safe:35	// const INST: &'static Self;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(params: Vec<Cow<'static, str>>, handler: impl NativeCallbackHandler) -> Self {46		Self {47			params: params48				.into_iter()49				.map(|n| BuiltinParam {50					name: Some(n),51					has_default: false,52				})53				.collect(),54			handler: tb!(handler),55		}56	}57}5859impl Builtin for NativeCallback {60	fn name(&self) -> &str {61		// TODO: standard natives gets their names from definition62		// But builitins should already have them63		"<native>"64	}6566	fn params(&self) -> &[BuiltinParam] {67		&self.params68	}6970	fn call(&self, ctx: Context, _loc: CallLocation<'_>, args: &dyn ArgsLike) -> Result<Val> {71		let args = parse_builtin_call(ctx, &self.params, args, true)?;72		let args = args73			.into_iter()74			.map(|a| a.expect("legacy natives have no default params"))75			.map(|a| a.evaluate())76			.collect::<Result<Vec<Val>>>()?;77		self.handler.call(&args)78	}79}8081pub trait NativeCallbackHandler: Trace {82	fn call(&self, args: &[Val]) -> Result<Val>;83}
after · crates/jrsonnet-evaluator/src/function/builtin.rs
1use std::{any::Any, borrow::Cow};23use jrsonnet_gcmodule::Trace;45use super::{arglike::ArgsLike, parse::parse_builtin_call, CallLocation};6use crate::{error::Result, gc::TraceBox, tb, Context, Val};78pub type BuiltinParamName = Cow<'static, str>;910#[derive(Clone, Trace)]11pub struct BuiltinParam {12	/// Parameter name for named call parsing13	pub name: Option<BuiltinParamName>,14	/// Is implementation allowed to return empty value15	pub has_default: bool,16}1718/// Description of function defined by native code19///20/// Prefer to use #[builtin] macro, instead of manual implementation of this trait21pub trait Builtin: Trace {22	/// Function name to be used in stack traces23	fn name(&self) -> &str;24	/// Parameter names for named calls25	fn params(&self) -> &[BuiltinParam];26	/// Call the builtin27	fn call(&self, ctx: Context, loc: CallLocation<'_>, args: &dyn ArgsLike) -> Result<Val>;2829	fn as_any(&self) -> &dyn Any;30}3132pub trait StaticBuiltin: Builtin + Send + Sync33where34	Self: 'static,35{36	// In impl, to make it object safe:37	// const INST: &'static Self;38}3940#[derive(Trace)]41pub struct NativeCallback {42	pub(crate) params: Vec<BuiltinParam>,43	handler: TraceBox<dyn NativeCallbackHandler>,44}45impl NativeCallback {46	#[deprecated = "prefer using builtins directly, use this interface only for bindings"]47	pub fn new(params: Vec<Cow<'static, str>>, handler: impl NativeCallbackHandler) -> Self {48		Self {49			params: params50				.into_iter()51				.map(|n| BuiltinParam {52					name: Some(n),53					has_default: false,54				})55				.collect(),56			handler: tb!(handler),57		}58	}59}6061impl Builtin for NativeCallback {62	fn name(&self) -> &str {63		// TODO: standard natives gets their names from definition64		// But builitins should already have them65		"<native>"66	}6768	fn params(&self) -> &[BuiltinParam] {69		&self.params70	}7172	fn call(&self, ctx: Context, _loc: CallLocation<'_>, args: &dyn ArgsLike) -> Result<Val> {73		let args = parse_builtin_call(ctx, &self.params, args, true)?;74		let args = args75			.into_iter()76			.map(|a| a.expect("legacy natives have no default params"))77			.map(|a| a.evaluate())78			.collect::<Result<Vec<Val>>>()?;79		self.handler.call(&args)80	}8182	fn as_any(&self) -> &dyn Any {83		self84	}85}8687pub trait NativeCallbackHandler: Trace {88	fn call(&self, args: &[Val]) -> Result<Val>;89}
modifiedcrates/jrsonnet-macros/src/lib.rsdiffbeforeafterboth
--- a/crates/jrsonnet-macros/src/lib.rs
+++ b/crates/jrsonnet-macros/src/lib.rs
@@ -380,6 +380,9 @@
 					let result: #result = #name(#(#pass)*);
 					<_ as Typed>::into_result(result)
 				}
+				fn as_any(&self) -> &dyn ::std::any::Any {
+					self
+				}
 			}
 		};
 	})