difftreelog
feat(evaluator) add ability to call functions with values
in: master
2 files changed
crates/jsonnet-evaluator/src/function.rsdiffbeforeafterboth--- a/crates/jsonnet-evaluator/src/function.rs
+++ b/crates/jsonnet-evaluator/src/function.rs
@@ -1,4 +1,4 @@
-use crate::{create_error, evaluate, lazy_val, resolved_lazy_val, Context, Error, Result};
+use crate::{create_error, evaluate, lazy_val, resolved_lazy_val, Context, Error, Result, Val};
use closure::closure;
use jsonnet_parser::{ArgsDesc, ParamsDesc};
use std::collections::HashMap;
@@ -78,3 +78,34 @@
Ok(body_ctx.unwrap_or(ctx).extend(out, None, None, None)?)
}
+
+#[inline(always)]
+pub(crate) fn place_args(
+ ctx: Context,
+ body_ctx: Option<Context>,
+ params: &ParamsDesc,
+ args: &[Val],
+) -> Result<Context> {
+ let mut out = HashMap::new();
+ let mut positioned_args = vec![None; params.0.len()];
+ for (id, arg) in args.iter().enumerate() {
+ if id >= params.len() {
+ create_error(Error::TooManyArgsFunctionHas(params.len()))?;
+ }
+ positioned_args[id] = Some(arg);
+ }
+ // Fill defaults
+ for (id, p) in params.iter().enumerate() {
+ let val = if let Some(arg) = &positioned_args[id] {
+ (*arg).clone()
+ } else if let Some(default) = &p.1 {
+ evaluate(ctx.clone(), default)?
+ } else {
+ create_error(Error::FunctionParameterNotBoundInCall(p.0.clone()))?;
+ unreachable!()
+ };
+ out.insert(p.0.clone(), resolved_lazy_val!(val));
+ }
+
+ Ok(body_ctx.unwrap_or(ctx).extend(out, None, None, None)?)
+}
crates/jsonnet-evaluator/src/val.rsdiffbeforeafterboth1use crate::{1use crate::{2 create_error, evaluate, function::inline_parse_function_call, Context, Error, ObjValue, Result,2 create_error, evaluate,3 function::{inline_parse_function_call, place_args},4 with_state, Context, Error, ObjValue, Result,3};5};4use jsonnet_parser::{el, Arg, ArgsDesc, Expr, LocExpr, ParamsDesc};6use jsonnet_parser::{el, Arg, ArgsDesc, Expr, LocExpr, ParamsDesc};5use std::{7use std::{87 evaluate(ctx, &self.body)89 evaluate(ctx, &self.body)88 }90 }9192 #[inline(always)]93 pub fn evaluate_values(&self, call_ctx: Context, args: &[Val]) -> Result<Val> {94 let ctx = place_args(call_ctx, Some(self.ctx.clone()), &self.params, args)?;95 evaluate(ctx, &self.body)96 }89}97}909891#[derive(Debug)]99#[derive(Debug)]