git.delta.rocks / jrsonnet / refs/commits / cf6d90fc07cc

difftreelog

refactor drop impl ArgsLike for HashMap

ywsrpypxYaroslav Bolyukin2026-03-22parent: #57e587b.patch.diff
in: master

2 files changed

modifiedcrates/jrsonnet-evaluator/src/function/arglike.rsdiffbeforeafterboth
89 }89 }
90}90}
91
92// TODO: Is this implementation really required, as there is no Context to use?
93// Maybe something a bit stricter is possible to add, especially with precompiled calls?
94impl ArgLike for TlaArg {
95 fn evaluate_arg(&self, _ctx: Context, tailstrict: bool) -> Result<Thunk<Val>> {
96 if tailstrict {
97 self.evaluate_tailstrict().map(Thunk::evaluated)
98 } else {
99 self.evaluate()
100 }
101 }
102}
10391
104pub trait ArgsLike {92pub trait ArgsLike {
105 fn unnamed_len(&self) -> usize;93 fn unnamed_len(&self) -> usize;
208 }196 }
209}197}
210
211impl<V: ArgLike, S> ArgsLike for HashMap<IStr, V, S> {
212 fn unnamed_len(&self) -> usize {
213 0
214 }
215
216 fn unnamed_iter(
217 &self,
218 _ctx: Context,
219 _tailstrict: bool,
220 _handler: &mut dyn FnMut(usize, Thunk<Val>) -> Result<()>,
221 ) -> Result<()> {
222 Ok(())
223 }
224
225 fn named_iter(
226 &self,
227 ctx: Context,
228 tailstrict: bool,
229 handler: &mut dyn FnMut(&IStr, Thunk<Val>) -> Result<()>,
230 ) -> Result<()> {
231 for (name, value) in self {
232 handler(name, value.evaluate_arg(ctx.clone(), tailstrict)?)?;
233 }
234 Ok(())
235 }
236
237 fn named_names(&self, handler: &mut dyn FnMut(&IStr)) {
238 for name in self.keys() {
239 handler(name);
240 }
241 }
242
243 fn is_empty(&self) -> bool {
244 self.is_empty()
245 }
246}
247
248macro_rules! impl_args_like {
249 ($count:expr; $($gen:ident)*) => {
250 impl<$($gen: ArgLike,)*> ArgsLike for ($($gen,)*) {
251 fn unnamed_len(&self) -> usize {
252 $count
253 }
254 #[allow(non_snake_case, unused_assignments)]
255 fn unnamed_iter(
256 &self,
257 ctx: Context,
258 tailstrict: bool,
259 handler: &mut dyn FnMut(usize, Thunk<Val>) -> Result<()>,
260 ) -> Result<()> {
261 let mut i = 0usize;
262 let ($($gen,)*) = self;
263 $(
264 handler(i, $gen.evaluate_arg(ctx.clone(), tailstrict)?)?;
265 i+=1;
266 )*
267 Ok(())
268 }
269 fn named_iter(
270 &self,
271 _ctx: Context,
272 _tailstrict: bool,
273 _handler: &mut dyn FnMut(&IStr, Thunk<Val>) -> Result<()>,
274 ) -> Result<()> {
275 Ok(())
276 }
277 fn named_names(&self, _handler: &mut dyn FnMut(&IStr)) {}
278
279 fn is_empty(&self) -> bool {
280 // impl_args_like only implements non-empty tuples.
281 false
282 }
283 }
284 };
285 ($count:expr; $($cur:ident)* @ $c:ident $($rest:ident)*) => {
286 impl_args_like!($count; $($cur)*);
287 impl_args_like!($count + 1usize; $($cur)* $c @ $($rest)*);
288 };
289 ($count:expr; $($cur:ident)* @) => {
290 impl_args_like!($count; $($cur)*);
291 }
292}
293impl_args_like! {
294 // First argument is already in position, so count starts from 1
295 1usize; A @ B C D E F G H I J K L
296}
297
298impl ArgsLike for () {
299 fn unnamed_len(&self) -> usize {
300 0
301 }
302
303 fn unnamed_iter(
304 &self,
305 _ctx: Context,
306 _tailstrict: bool,
307 _handler: &mut dyn FnMut(usize, Thunk<Val>) -> Result<()>,
308 ) -> Result<()> {
309 Ok(())
310 }
311
312 fn named_iter(
313 &self,
314 _ctx: Context,
315 _tailstrict: bool,
316 _handler: &mut dyn FnMut(&IStr, Thunk<Val>) -> Result<()>,
317 ) -> Result<()> {
318 Ok(())
319 }
320
321 fn named_names(&self, _handler: &mut dyn FnMut(&IStr)) {}
322 fn is_empty(&self) -> bool {
323 true
324 }
325}
326198
modifiedcrates/jrsonnet-evaluator/src/tla.rsdiffbeforeafterboth
1use std::{collections::HashMap, hash::BuildHasher};1use std::{collections::HashMap, hash::BuildHasher};
22
3use jrsonnet_interner::IStr;3use jrsonnet_interner::IStr;
4use jrsonnet_parser::Source;
54
6use crate::{5use crate::{
7 function::{CallLocation, TlaArg},6 function::{CallLocation, PreparedFuncVal, TlaArg},
8 in_description_frame, with_state, Result, Val,7 in_description_frame, Result, Val,
9};8};
109
11pub fn apply_tla<H: BuildHasher>(args: &HashMap<IStr, TlaArg, H>, val: Val) -> Result<Val> {10pub fn apply_tla<H: BuildHasher>(args: &HashMap<IStr, TlaArg, H>, val: Val) -> Result<Val> {
12 Ok(if let Val::Func(func) = val {11 Ok(if let Val::Func(func) = val {
13 in_description_frame(12 in_description_frame(
14 || "during TLA call".to_owned(),13 || "during TLA call".to_owned(),
15 || {14 || {
16 func.evaluate(15 let mut names = Vec::with_capacity(args.len());
17 with_state(|s| {16 let mut values = Vec::with_capacity(args.len());
17 for (name, value) in args {
18 s.create_default_context(Source::new_virtual(18 names.push(name.clone());
19 "<top-level-arg>".into(),
20 IStr::empty(),
21 ))
22 }),
23 CallLocation::native(),19 values.push(value.evaluate()?);
24 args,20 }
25 false,21 let prepared = PreparedFuncVal::new(func, 0, &names)?;
26 )22 prepared.call(CallLocation::native(), &[], &values)
27 },23 },
28 )?24 )?
29 } else {25 } else {