difftreelog
refactor drop impl ArgsLike for HashMap
in: master
2 files changed
crates/jrsonnet-evaluator/src/function/arglike.rsdiffbeforeafterboth1use std::collections::HashMap;2use std::rc::Rc;34use jrsonnet_gcmodule::Trace;5use jrsonnet_interner::IStr;6use jrsonnet_parser::{ArgsDesc, Expr, SourceFifo, SourcePath, Spanned};78use crate::{evaluate, typed::Typed, with_state, Context, Result, Thunk, Val};910pub trait ArgLike {11 fn evaluate_arg(&self, ctx: Context, tailstrict: bool) -> Result<Thunk<Val>>;12}1314impl ArgLike for &Rc<Spanned<Expr>> {15 fn evaluate_arg(&self, ctx: Context, tailstrict: bool) -> Result<Thunk<Val>> {16 Ok(if tailstrict {17 Thunk::evaluated(evaluate(ctx, self)?)18 } else {19 let expr = (*self).clone();20 Thunk!(move || evaluate(ctx, &expr))21 })22 }23}2425impl<T> ArgLike for T26where27 T: Typed + Clone,28{29 fn evaluate_arg(&self, _ctx: Context, tailstrict: bool) -> Result<Thunk<Val>> {30 if T::provides_lazy() && !tailstrict {31 return Ok(T::into_lazy_untyped(self.clone()));32 }33 let val = T::into_untyped(self.clone())?;34 Ok(Thunk::evaluated(val))35 }36}3738#[derive(Clone, Trace)]39pub enum TlaArg {40 String(IStr),41 Val(Val),42 Lazy(Thunk<Val>),43 Import(String),44 ImportStr(String),45 InlineCode(String),46}47impl TlaArg {48 pub fn evaluate_tailstrict(&self) -> Result<Val> {49 match self {50 Self::String(s) => Ok(Val::string(s.clone())),51 Self::Val(val) => Ok(val.clone()),52 Self::Lazy(lazy) => Ok(lazy.evaluate()?),53 Self::Import(p) => with_state(|s| {54 let resolved = s.resolve_from_default(&p.as_str())?;55 s.import_resolved(resolved)56 }),57 Self::ImportStr(p) => with_state(|s| {58 let resolved = s.resolve_from_default(&p.as_str())?;59 s.import_resolved_str(resolved).map(Val::string)60 }),61 Self::InlineCode(p) => with_state(|s| {62 let resolved =63 SourcePath::new(SourceFifo("<inline code>".to_owned(), p.as_bytes().into()));64 s.import_resolved(resolved)65 }),66 }67 }68 pub fn evaluate(&self) -> Result<Thunk<Val>> {69 match self {70 Self::String(s) => Ok(Thunk::evaluated(Val::string(s.clone()))),71 Self::Val(val) => Ok(Thunk::evaluated(val.clone())),72 Self::Lazy(lazy) => Ok(lazy.clone()),73 Self::Import(p) => with_state(|s| {74 let resolved = s.resolve_from_default(&p.as_str())?;75 Ok(Thunk!(move || s.import_resolved(resolved)))76 }),77 Self::ImportStr(p) => with_state(|s| {78 let resolved = s.resolve_from_default(&p.as_str())?;79 Ok(Thunk!(move || s80 .import_resolved_str(resolved)81 .map(Val::string)))82 }),83 Self::InlineCode(p) => with_state(|s| {84 let resolved =85 SourcePath::new(SourceFifo("<inline code>".to_owned(), p.as_bytes().into()));86 Ok(Thunk!(move || s.import_resolved(resolved)))87 }),88 }89 }90}9192pub trait ArgsLike {93 fn unnamed_len(&self) -> usize;94 fn unnamed_iter(95 &self,96 ctx: Context,97 tailstrict: bool,98 handler: &mut dyn FnMut(usize, Thunk<Val>) -> Result<()>,99 ) -> Result<()>;100 fn named_iter(101 &self,102 ctx: Context,103 tailstrict: bool,104 handler: &mut dyn FnMut(&IStr, Thunk<Val>) -> Result<()>,105 ) -> Result<()>;106 fn named_names(&self, handler: &mut dyn FnMut(&IStr));107 fn is_empty(&self) -> bool;108}109110impl ArgsLike for Vec<Val> {111 fn unnamed_len(&self) -> usize {112 self.len()113 }114 fn unnamed_iter(115 &self,116 _ctx: Context,117 _tailstrict: bool,118 handler: &mut dyn FnMut(usize, Thunk<Val>) -> Result<()>,119 ) -> Result<()> {120 for (idx, el) in self.iter().enumerate() {121 handler(idx, Thunk::evaluated(el.clone()))?;122 }123 Ok(())124 }125 fn named_iter(126 &self,127 _ctx: Context,128 _tailstrict: bool,129 _handler: &mut dyn FnMut(&IStr, Thunk<Val>) -> Result<()>,130 ) -> Result<()> {131 Ok(())132 }133 fn named_names(&self, _handler: &mut dyn FnMut(&IStr)) {}134 fn is_empty(&self) -> bool {135 self.is_empty()136 }137}138139impl ArgsLike for ArgsDesc {140 fn unnamed_len(&self) -> usize {141 self.unnamed.len()142 }143144 fn unnamed_iter(145 &self,146 ctx: Context,147 tailstrict: bool,148 handler: &mut dyn FnMut(usize, Thunk<Val>) -> Result<()>,149 ) -> Result<()> {150 for (id, arg) in self.unnamed.iter().enumerate() {151 handler(152 id,153 if tailstrict {154 Thunk::evaluated(evaluate(ctx.clone(), arg)?)155 } else {156 let ctx = ctx.clone();157 let arg = arg.clone();158159 Thunk!(move || evaluate(ctx, &arg))160 },161 )?;162 }163 Ok(())164 }165166 fn named_iter(167 &self,168 ctx: Context,169 tailstrict: bool,170 handler: &mut dyn FnMut(&IStr, Thunk<Val>) -> Result<()>,171 ) -> Result<()> {172 for (name, arg) in &self.named {173 handler(174 name,175 if tailstrict {176 Thunk::evaluated(evaluate(ctx.clone(), arg)?)177 } else {178 let ctx = ctx.clone();179 let arg = arg.clone();180181 Thunk!(move || evaluate(ctx, &arg))182 },183 )?;184 }185 Ok(())186 }187188 fn named_names(&self, handler: &mut dyn FnMut(&IStr)) {189 for (name, _) in &self.named {190 handler(name);191 }192 }193194 fn is_empty(&self) -> bool {195 self.unnamed.is_empty() && self.named.is_empty()196 }197}crates/jrsonnet-evaluator/src/tla.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/tla.rs
+++ b/crates/jrsonnet-evaluator/src/tla.rs
@@ -1,11 +1,10 @@
use std::{collections::HashMap, hash::BuildHasher};
use jrsonnet_interner::IStr;
-use jrsonnet_parser::Source;
use crate::{
- function::{CallLocation, TlaArg},
- in_description_frame, with_state, Result, Val,
+ function::{CallLocation, PreparedFuncVal, TlaArg},
+ in_description_frame, Result, Val,
};
pub fn apply_tla<H: BuildHasher>(args: &HashMap<IStr, TlaArg, H>, val: Val) -> Result<Val> {
@@ -13,17 +12,14 @@
in_description_frame(
|| "during TLA call".to_owned(),
|| {
- func.evaluate(
- with_state(|s| {
- s.create_default_context(Source::new_virtual(
- "<top-level-arg>".into(),
- IStr::empty(),
- ))
- }),
- CallLocation::native(),
- args,
- false,
- )
+ let mut names = Vec::with_capacity(args.len());
+ let mut values = Vec::with_capacity(args.len());
+ for (name, value) in args {
+ names.push(name.clone());
+ values.push(value.evaluate()?);
+ }
+ let prepared = PreparedFuncVal::new(func, 0, &names)?;
+ prepared.call(CallLocation::native(), &[], &values)
},
)?
} else {