difftreelog
feat --exp-apply argument
in: master
3 files changed
cmds/jrsonnet/Cargo.tomldiffbeforeafterboth8edition = "2021"8edition = "2021"9910[features]10[features]11experimental = ["exp-preserve-order", "exp-destruct"]11experimental = ["exp-preserve-order", "exp-destruct", "exp-null-coaelse", "exp-object-iteration", "exp-bigint", "exp-apply"]12# Use mimalloc as allocator12# Use mimalloc as allocator13mimalloc = ["mimallocator"]13mimalloc = ["mimallocator"]14# Experimental feature, which allows to preserve order of object fields14# Experimental feature, which allows to preserve order of object fields22exp-object-iteration = ["jrsonnet-evaluator/exp-object-iteration"]22exp-object-iteration = ["jrsonnet-evaluator/exp-object-iteration"]23# Bigint type23# Bigint type24exp-bigint = ["jrsonnet-evaluator/exp-bigint", "jrsonnet-cli/exp-bigint"]24exp-bigint = ["jrsonnet-evaluator/exp-bigint", "jrsonnet-cli/exp-bigint"]25# obj?.field, obj?.['field']26exp-null-coaelse = ["jrsonnet-evaluator/exp-null-coaelse", "jrsonnet-parser/exp-null-coaelse"]27# --exp-apply28exp-apply = []252926# std.thisFile support30# std.thisFile support27legacy-this-file = ["jrsonnet-cli/legacy-this-file"]31legacy-this-file = ["jrsonnet-cli/legacy-this-file"]cmds/jrsonnet/src/main.rsdiffbeforeafterboth44 /// Path to the file to be compiled if `--evaluate` is unset, otherwise code itself44 /// Path to the file to be compiled if `--evaluate` is unset, otherwise code itself45 pub input: Option<String>,45 pub input: Option<String>,4647 /// After executing input, apply specified code.48 /// Output of the initial input will be accessible using `$`49 #[cfg(feature = "exp-apply")]50 #[clap(long)]51 pub exp_apply: Vec<String>,46}52}475348/// Jsonnet commandline interpreter (Rust implementation)54/// Jsonnet commandline interpreter (Rust implementation)181 };187 };182188183 let tla = opts.tla.tla_opts()?;189 let tla = opts.tla.tla_opts()?;190 #[allow(unused_mut)]184 let val = apply_tla(s.clone(), &tla, val)?;191 let mut val = apply_tla(s.clone(), &tla, val)?;192193 #[cfg(feature = "exp-apply")]194 for apply in opts.input.exp_apply {195 use jrsonnet_evaluator::{InitialUnderscore, Thunk};196 val = s.evaluate_snippet_with(197 "<exp_apply>".to_owned(),198 &apply,199 InitialUnderscore(Thunk::evaluated(val)),200 )?;201 }185202186 let manifest_format = opts.manifest.manifest_format();203 let manifest_format = opts.manifest.manifest_format();187 if let Some(multi) = opts.output.multi {204 if let Some(multi) = opts.output.multi {crates/jrsonnet-evaluator/src/lib.rsdiffbeforeafterboth154 }154 }155}155}156157macro_rules! impl_context_initializer {158 ($($gen:ident)*) => {159 #[allow(non_snake_case)]160 impl<$($gen: ContextInitializer + Trace,)*> ContextInitializer for ($($gen,)*) {161 fn reserve_vars(&self) -> usize {162 let mut out = 0;163 let ($($gen,)*) = self;164 $(out += $gen.reserve_vars();)*165 out166 }167 fn populate(&self, for_file: Source, builder: &mut ContextBuilder) {168 let ($($gen,)*) = self;169 $($gen.populate(for_file.clone(), builder);)*170 }171 fn as_any(&self) -> &dyn Any {172 self173 }174 }175 };176 ($($cur:ident)* @ $c:ident $($rest:ident)*) => {177 impl_context_initializer!($($cur)*);178 impl_context_initializer!($($cur)* $c @ $($rest)*);179 };180 ($($cur:ident)* @) => {181 impl_context_initializer!($($cur)*);182 }183}184impl_context_initializer! {185 A B @ C D E186}156187157/// Dynamically reconfigurable evaluation settings188/// Dynamically reconfigurable evaluation settings158#[derive(Trace)]189#[derive(Trace)]361 context_initializer.initialize(self.clone(), source)392 context_initializer.initialize(self.clone(), source)362 }393 }394395 /// Creates context with all passed global variables, calling custom modifier396 pub fn create_default_context_with(397 &self,398 source: Source,399 context_initializer: impl ContextInitializer,400 ) -> Context {401 let default_initializer = &self.settings().context_initializer;402 let mut builder = ContextBuilder::with_capacity(403 self.clone(),404 default_initializer.reserve_vars() + context_initializer.reserve_vars(),405 );406 default_initializer.populate(source.clone(), &mut builder);407 context_initializer.populate(source, &mut builder);408409 builder.build()410 }363411364 /// Executes code creating a new stack frame412 /// Executes code creating a new stack frame365 pub fn push<T>(413 pub fn push<T>(428 }476 }429 let mut settings = self.settings_mut();477 let mut settings = self.settings_mut();430 let initializer = &mut settings.context_initializer;478 let initializer = &mut settings.context_initializer;431 match initializer.as_any().downcast_ref::<GlobalsCtx>() {479 if let Some(global) = initializer.as_any().downcast_ref::<GlobalsCtx>() {432 Some(glob) => {480 global.globals.borrow_mut().insert(name, value);433 glob.globals.borrow_mut().insert(name, value);434 }481 } else {435 None => {436 let inner = std::mem::replace(&mut settings.context_initializer, tb!(()));482 let inner = std::mem::replace(&mut settings.context_initializer, tb!(()));437 settings.context_initializer = tb!(GlobalsCtx {483 settings.context_initializer = tb!(GlobalsCtx {438 globals: {484 globals: {441 RefCell::new(out)487 RefCell::new(out)442 },488 },443 inner489 inner444 })490 });445 }491 }446 }447 }492 }448}493}494495#[derive(Trace)]496pub struct InitialUnderscore(pub Thunk<Val>);497impl ContextInitializer for InitialUnderscore {498 fn populate(&self, _for_file: Source, builder: &mut ContextBuilder) {499 builder.bind("_".into(), self.0.clone());500 }501502 fn as_any(&self) -> &dyn Any {503 self504 }505}449506450/// Raw methods evaluate passed values but don't perform TLA execution507/// Raw methods evaluate passed values but don't perform TLA execution451impl State {508impl State {465 })?;522 })?;466 evaluate(self.create_default_context(source), &parsed)523 evaluate(self.create_default_context(source), &parsed)467 }524 }525 /// Parses and evaluates the given snippet with custom context modifier526 pub fn evaluate_snippet_with(527 &self,528 name: impl Into<IStr>,529 code: impl Into<IStr>,530 context_initializer: impl ContextInitializer,531 ) -> Result<Val> {532 let code = code.into();533 let source = Source::new_virtual(name.into(), code.clone());534 let parsed = jrsonnet_parser::parse(535 &code,536 &ParserSettings {537 source: source.clone(),538 },539 )540 .map_err(|e| ImportSyntaxError {541 path: source.clone(),542 error: Box::new(e),543 })?;544 evaluate(545 self.create_default_context_with(source, context_initializer),546 &parsed,547 )548 }468}549}469550470/// Settings utilities551/// Settings utilities