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