git.delta.rocks / jrsonnet / refs/commits / 5df60b8b674f

difftreelog

style fix clippy warnings

rvmlxxrnYaroslav Bolyukin2026-03-21parent: #ac5b435.patch.diff
in: master

36 files changed

modifiedbindings/jsonnet/src/native.rsdiffbeforeafterboth
43 }43 }
44 n_args.push(None);44 n_args.push(None);
45 let mut success = 1;45 let mut success = 1;
46 let v = unsafe { (self.cb)(self.ctx, n_args.as_ptr().cast(), &mut success) };46 let v = unsafe { (self.cb)(self.ctx, n_args.as_ptr().cast(), &raw mut success) };
47 let v = unsafe { *Box::from_raw(v) };47 let v = unsafe { *Box::from_raw(v) };
48 if success == 1 {48 if success == 1 {
49 Ok(v)49 Ok(v)
modifiedcrates/jrsonnet-cli/src/tla.rsdiffbeforeafterboth
77
8#[derive(Parser)]8#[derive(Parser)]
9#[clap(next_help_heading = "TOP LEVEL ARGUMENTS")]9#[clap(next_help_heading = "TOP LEVEL ARGUMENTS")]
10#[allow(clippy::struct_field_names)]
10pub struct TlaOpts {11pub struct TlaOpts {
11 /// Add top level string argument.12 /// Add top level string argument.
12 /// Top level arguments will be passed to function before manifestification stage.13 /// Top level arguments will be passed to function before manifestification stage.
modifiedcrates/jrsonnet-evaluator/src/arr/mod.rsdiffbeforeafterboth
77 let i = i?;77 let i = i?;
78 if filter(&i)? {78 if filter(&i)? {
79 out.push(i);79 out.push(i);
80 };80 }
81 }81 }
82 Ok(Self::eager(out))82 Ok(Self::eager(out))
83 }83 }
modifiedcrates/jrsonnet-evaluator/src/arr/spec.rsdiffbeforeafterboth
38}38}
39impl ArrayLike for SliceArray {39impl ArrayLike for SliceArray {
40 fn len(&self) -> usize {40 fn len(&self) -> usize {
41 ((self.to - self.from + self.step - 1) / self.step) as usize41 (self.to - self.from).div_ceil(self.step) as usize
42 }42 }
4343
44 fn get(&self, index: usize) -> Result<Option<Val>> {44 fn get(&self, index: usize) -> Result<Option<Val>> {
139 ArrayThunk::Errored(e) => return Err(e.clone()),139 ArrayThunk::Errored(e) => return Err(e.clone()),
140 ArrayThunk::Pending => return Err(InfiniteRecursionDetected.into()),140 ArrayThunk::Pending => return Err(InfiniteRecursionDetected.into()),
141 ArrayThunk::Waiting => {}141 ArrayThunk::Waiting => {}
142 };142 }
143143
144 let ArrayThunk::Waiting =144 let ArrayThunk::Waiting =
145 replace(&mut self.cached.borrow_mut()[index], ArrayThunk::Pending)145 replace(&mut self.cached.borrow_mut()[index], ArrayThunk::Pending)
158 Ok(Some(new_value))158 Ok(Some(new_value))
159 }159 }
160 fn get_lazy(&self, index: usize) -> Option<Thunk<Val>> {160 fn get_lazy(&self, index: usize) -> Option<Thunk<Val>> {
161 #[derive(Trace)]
162 struct ExprArrThunk {
163 expr: ExprArray,
164 index: usize,
165 }
166 impl ThunkValue for ExprArrThunk {
167 type Output = Val;
168
169 fn get(&self) -> Result<Self::Output> {
170 self.expr
171 .get(self.index)
172 .transpose()
173 .expect("index checked")
174 }
175 }
176
161 if index >= self.len() {177 if index >= self.len() {
162 return None;178 return None;
165 ArrayThunk::Computed(c) => return Some(Thunk::evaluated(c.clone())),181 ArrayThunk::Computed(c) => return Some(Thunk::evaluated(c.clone())),
166 ArrayThunk::Errored(e) => return Some(Thunk::errored(e.clone())),182 ArrayThunk::Errored(e) => return Some(Thunk::errored(e.clone())),
167 ArrayThunk::Waiting | ArrayThunk::Pending => {}183 ArrayThunk::Waiting | ArrayThunk::Pending => {}
168 };184 }
169
170 #[derive(Trace)]
171 struct ExprArrThunk {
172 expr: ExprArray,
173 index: usize,
174 }
175 impl ThunkValue for ExprArrThunk {
176 type Output = Val;
177
178 fn get(&self) -> Result<Self::Output> {
179 self.expr
180 .get(self.index)
181 .transpose()
182 .expect("index checked")
183 }
184 }
185185
186 Some(Thunk::new(ExprArrThunk {186 Some(Thunk::new(ExprArrThunk {
187 expr: self.clone(),187 expr: self.clone(),
441 ArrayThunk::Errored(e) => return Err(e.clone()),441 ArrayThunk::Errored(e) => return Err(e.clone()),
442 ArrayThunk::Pending => return Err(InfiniteRecursionDetected.into()),442 ArrayThunk::Pending => return Err(InfiniteRecursionDetected.into()),
443 ArrayThunk::Waiting => {}443 ArrayThunk::Waiting => {}
444 };444 }
445445
446 let ArrayThunk::Waiting =446 let ArrayThunk::Waiting =
447 replace(&mut self.cached.borrow_mut()[index], ArrayThunk::Pending)447 replace(&mut self.cached.borrow_mut()[index], ArrayThunk::Pending)
467 Ok(Some(new_value))467 Ok(Some(new_value))
468 }468 }
469 fn get_lazy(&self, index: usize) -> Option<Thunk<Val>> {469 fn get_lazy(&self, index: usize) -> Option<Thunk<Val>> {
470 #[derive(Trace)]
471 struct MappedArrayThunk<const WITH_INDEX: bool> {
472 arr: MappedArray<WITH_INDEX>,
473 index: usize,
474 }
475 impl<const WITH_INDEX: bool> ThunkValue for MappedArrayThunk<WITH_INDEX> {
476 type Output = Val;
477
478 fn get(&self) -> Result<Self::Output> {
479 self.arr.get(self.index).transpose().expect("index checked")
480 }
481 }
482
470 if index >= self.len() {483 if index >= self.len() {
471 return None;484 return None;
474 ArrayThunk::Computed(c) => return Some(Thunk::evaluated(c.clone())),487 ArrayThunk::Computed(c) => return Some(Thunk::evaluated(c.clone())),
475 ArrayThunk::Errored(e) => return Some(Thunk::errored(e.clone())),488 ArrayThunk::Errored(e) => return Some(Thunk::errored(e.clone())),
476 ArrayThunk::Waiting | ArrayThunk::Pending => {}489 ArrayThunk::Waiting | ArrayThunk::Pending => {}
477 };490 }
478
479 #[derive(Trace)]
480 struct MappedArrayThunk<const WITH_INDEX: bool> {
481 arr: MappedArray<WITH_INDEX>,
482 index: usize,
483 }
484 impl<const WITH_INDEX: bool> ThunkValue for MappedArrayThunk<WITH_INDEX> {
485 type Output = Val;
486
487 fn get(&self) -> Result<Self::Output> {
488 self.arr.get(self.index).transpose().expect("index checked")
489 }
490 }
491491
492 Some(Thunk::new(MappedArrayThunk {492 Some(Thunk::new(MappedArrayThunk {
493 arr: self.clone(),493 arr: self.clone(),
modifiedcrates/jrsonnet-evaluator/src/async_import.rsdiffbeforeafterboth
21// Visits all nodes, trying to find import statements21// Visits all nodes, trying to find import statements
22#[allow(clippy::too_many_lines)]22#[allow(clippy::too_many_lines)]
23pub fn find_imports(expr: &Spanned<Expr>, out: &mut FoundImports) {23pub fn find_imports(expr: &Spanned<Expr>, out: &mut FoundImports) {
24 #[allow(unused_variables, clippy::needless_pass_by_ref_mut)]
24 fn in_destruct(dest: &Destruct, #[allow(unused_variables)] out: &mut FoundImports) {25 fn in_destruct(dest: &Destruct, out: &mut FoundImports) {
25 match dest {26 match dest {
26 #[cfg(feature = "exp-destruct")]27 #[cfg(feature = "exp-destruct")]
27 Destruct::Array {28 Destruct::Array {
296 .downcast_ref::<ResolvedImportResolver>()297 .downcast_ref::<ResolvedImportResolver>()
297 .expect("for async imports, import_resolver should be set to ResolvedImportResolver");298 .expect("for async imports, import_resolver should be set to ResolvedImportResolver");
298
299 let mut resolved_map = resolved.resolved.borrow_mut();
300299
301 let mut queue = vec![Job::LoadFile {300 let mut queue = vec![Job::LoadFile {
302 path: handler.resolve_from_default(path).await?,301 path: handler.resolve_from_default(path).await?,
340 }339 }
341 }340 }
342 Job::ResolveImport { from, import } => {341 Job::ResolveImport { from, import } => {
342 {
343 let mut resolved_map = resolved.resolved.borrow_mut();
343 if let Some((resolved, expression)) =344 if let Some((resolved, expression)) =
344 resolved_map.get_mut(&(from.clone(), import.path.clone()))345 resolved_map.get_mut(&(from.clone(), import.path.clone()))
345 {346 {
349 }350 }
350 continue;351 continue;
351 }352 }
353 }
352 let resolved = handler.resolve_from(&from, &import.path).await?;354 let resolved = handler.resolve_from(&from, &import.path).await?;
353 queue.push(Job::LoadFile {355 queue.push(Job::LoadFile {
354 path: resolved,356 path: resolved,
modifiedcrates/jrsonnet-evaluator/src/evaluate/destructure.rsdiffbeforeafterboth
1use std::{collections::HashMap, hash::BuildHasher};
2
1use jrsonnet_interner::IStr;3use jrsonnet_interner::IStr;
2use jrsonnet_parser::{BindSpec, Destruct};4use jrsonnet_parser::{BindSpec, Destruct};
3use rustc_hash::FxHashMap;
45
5use crate::{6use crate::{
6 bail,7 bail,
1011
11#[allow(clippy::too_many_lines)]12#[allow(clippy::too_many_lines)]
12#[allow(unused_variables)]13#[allow(unused_variables)]
13pub fn destruct(14pub fn destruct<H: BuildHasher>(
14 d: &Destruct,15 d: &Destruct,
15 parent: Thunk<Val>,16 parent: Thunk<Val>,
16 fctx: Pending<Context>,17 fctx: Pending<Context>,
17 new_bindings: &mut FxHashMap<IStr, Thunk<Val>>,18 new_bindings: &mut HashMap<IStr, Thunk<Val>, H>,
18) -> Result<()> {19) -> Result<()> {
19 match d {20 match d {
20 Destruct::Full(v) => {21 Destruct::Full(v) => {
159 Ok(())160 Ok(())
160}161}
161162
162pub fn evaluate_dest(163pub fn evaluate_dest<H: BuildHasher>(
163 d: &BindSpec,164 d: &BindSpec,
164 fctx: Pending<Context>,165 fctx: Pending<Context>,
165 new_bindings: &mut FxHashMap<IStr, Thunk<Val>>,166 new_bindings: &mut HashMap<IStr, Thunk<Val>, H>,
166) -> Result<()> {167) -> Result<()> {
167 match d {168 match d {
168 BindSpec::Field { into, value } => {169 BindSpec::Field { into, value } => {
modifiedcrates/jrsonnet-evaluator/src/evaluate/mod.rsdiffbeforeafterboth
291 let uctx = CachedUnbound::new(evaluate_object_locals(ctx.clone(), locals));291 let uctx = CachedUnbound::new(evaluate_object_locals(ctx.clone(), locals));
292292
293 for field in &members.fields {293 for field in &members.fields {
294 evaluate_field_member(&mut builder, ctx.clone(), uctx.clone(), &field)?;294 evaluate_field_member(&mut builder, ctx.clone(), uctx.clone(), field)?;
295 }295 }
296296
297 if !members.asserts.is_empty() {297 if !members.asserts.is_empty() {
304 fn run(&self, sup_this: SupThis) -> Result<()> {304 fn run(&self, sup_this: SupThis) -> Result<()> {
305 let ctx = self.uctx.bind(sup_this)?;305 let ctx = self.uctx.bind(sup_this)?;
306 for assert in &*self.asserts {306 for assert in &*self.asserts {
307 evaluate_assert(ctx.clone(), &assert)?;307 evaluate_assert(ctx.clone(), assert)?;
308 }308 }
309 Ok(())309 Ok(())
310 }310 }
311 }311 }
312 builder.assert(ObjectAssert {312 builder.assert(ObjectAssert {
313 uctx: uctx.clone(),313 uctx,
314 asserts: members.asserts.clone(),314 asserts: members.asserts.clone(),
315 });315 });
316 }316 }
567 evaluate_dest(b, fctx.clone(), &mut new_bindings)?;567 evaluate_dest(b, fctx.clone(), &mut new_bindings)?;
568 }568 }
569 let ctx = ctx.extend_bindings(new_bindings).into_future(fctx);569 let ctx = ctx.extend_bindings(new_bindings).into_future(fctx);
570 evaluate(ctx, &returned.clone())?570 evaluate(ctx, returned)?
571 }571 }
572 Arr(items) => {572 Arr(items) => {
573 if items.is_empty() {573 if items.is_empty() {
modifiedcrates/jrsonnet-evaluator/src/evaluate/operator.rsdiffbeforeafterboth
95 // string format95 // string format
96 (Str(_), _) => false,96 (Str(_), _) => false,
9797
98 (_, Num(b)) => return **b == 0.,98 (_, Num(b)) => **b == 0.,
99 #[cfg(feature = "exp-bigint")]99 #[cfg(feature = "exp-bigint")]
100 (_, BigInt(b)) => return **b == num_bigint::BigInt::ZERO,100 (_, BigInt(b)) => **b == num_bigint::BigInt::ZERO,
101101
102 // something else102 // something else
103 _ => false,103 _ => false,
modifiedcrates/jrsonnet-evaluator/src/function/arglike.rsdiffbeforeafterboth
239 }239 }
240240
241 fn named_names(&self, handler: &mut dyn FnMut(&IStr)) {241 fn named_names(&self, handler: &mut dyn FnMut(&IStr)) {
242 for (name, _) in self {242 for name in self.keys() {
243 handler(name);243 handler(name);
244 }244 }
245 }245 }
modifiedcrates/jrsonnet-evaluator/src/function/parse.rsdiffbeforeafterboth
1use std::mem::replace;
2
3use jrsonnet_parser::{1use jrsonnet_parser::{
4 function::{FunctionSignature, ParamName},2 function::{FunctionSignature, ParamName},
87 }85 }
8886
89 destruct(87 destruct(
90 &into,88 into,
91 {89 {
92 let ctx = fctx.clone();90 let ctx = fctx.clone();
93 let name = into.name();91 let name = into.name();
97 fctx.clone(),95 fctx.clone(),
98 &mut defaults,96 &mut defaults,
99 )?;97 )?;
100 if !into.name().is_anonymous() {98 if into.name().is_named() {
101 filled_named += 1;99 filled_named += 1;
102 } else {100 } else {
103 filled_positionals += 1;101 filled_positionals += 1;
165 .iter()163 .iter()
166 .position(|p| p.name() == name)164 .position(|p| p.name() == name)
167 .ok_or_else(|| UnknownFunctionParameter(name.clone()))?;165 .ok_or_else(|| UnknownFunctionParameter(name.clone()))?;
168 if replace(&mut passed_args[id], Some(arg)).is_some() {166 if passed_args[id].replace(arg).is_some() {
169 bail!(BindingParameterASecondTime(name.clone()));167 bail!(BindingParameterASecondTime(name.clone()));
170 }168 }
171 filled_args += 1;169 filled_args += 1;
230 let params = params.clone();228 let params = params.clone();
231 Thunk!(move || Err(FunctionParameterNotBoundInCall(229 Thunk!(move || Err(FunctionParameterNotBoundInCall(
232 param_name,230 param_name,
233 params.signature.clone()231 params.signature
234 )232 )
235 .into()))233 .into()))
236 },234 },
modifiedcrates/jrsonnet-evaluator/src/gc.rsdiffbeforeafterboth
1#![allow(
2 clippy::implicit_hasher,
3 reason = "those methods exist exactly because with_capacity is only present for default BuildHasher"
4)]
5
1/// Macros to help deal with Gc6/// Macros to help deal with Gc
2use jrsonnet_gcmodule::Trace;7use jrsonnet_gcmodule::Trace;
8}13}
9impl<V> WithCapacityExt for FxHashSet<V> {14impl<V> WithCapacityExt for FxHashSet<V> {
10 fn with_capacity(capacity: usize) -> Self {15 fn with_capacity(capacity: usize) -> Self {
11 Self::with_capacity_and_hasher(capacity, FxBuildHasher::default())16 Self::with_capacity_and_hasher(capacity, FxBuildHasher)
12 }17 }
1318
14 fn new() -> Self {19 fn new() -> Self {
15 Self::with_hasher(FxBuildHasher::default())20 Self::with_hasher(FxBuildHasher)
16 }21 }
17}22}
18impl<K, V> WithCapacityExt for FxHashMap<K, V> {23impl<K, V> WithCapacityExt for FxHashMap<K, V> {
19 fn with_capacity(capacity: usize) -> Self {24 fn with_capacity(capacity: usize) -> Self {
20 Self::with_capacity_and_hasher(capacity, FxBuildHasher::default())25 Self::with_capacity_and_hasher(capacity, FxBuildHasher)
21 }26 }
2227
23 fn new() -> Self {28 fn new() -> Self {
24 Self::with_hasher(FxBuildHasher::default())29 Self::with_hasher(FxBuildHasher)
25 }30 }
26}31}
2732
modifiedcrates/jrsonnet-evaluator/src/lib.rsdiffbeforeafterboth
367 let res = evaluate(self.create_default_context(file_name), &parsed);367 let res = evaluate(self.create_default_context(file_name), &parsed);
368368
369 let mut file_cache = self.file_cache();369 let mut file_cache = self.file_cache();
370 let mut file = file_cache.entry(path.clone());370 let mut file = file_cache.entry(path);
371371
372 let Entry::Occupied(file) = &mut file else {372 let Entry::Occupied(file) = &mut file else {
373 unreachable!("this file was just here")373 unreachable!("this file was just here")
modifiedcrates/jrsonnet-evaluator/src/manifest.rsdiffbeforeafterboth
240 }240 }
241 ToString if i != 0 => buf.push(' '),241 ToString if i != 0 => buf.push(' '),
242 Minify | ToString => {}242 Minify | ToString => {}
243 };243 }
244244
245 in_description_frame(245 in_description_frame(
246 || format!("elem <{i}> manifestification"),246 || format!("elem <{i}> manifestification"),
335 buf.push('}');335 buf.push('}');
336 }336 }
337 Val::Func(_) => bail!("tried to manifest function"),337 Val::Func(_) => bail!("tried to manifest function"),
338 };338 }
339 Ok(())339 Ok(())
340}340}
341341
modifiedcrates/jrsonnet-evaluator/src/map.rsdiffbeforeafterboth
1616
17impl LayeredHashMap {17impl LayeredHashMap {
18 pub fn iter_keys(self, mut handler: impl FnMut(IStr)) {18 pub fn iter_keys(self, mut handler: impl FnMut(IStr)) {
19 for (k, _) in &self.0.current {19 for k in self.0.current.keys() {
20 handler(k.clone());20 handler(k.clone());
21 }21 }
22 if let Some(parent) = self.0.parent.clone() {22 if let Some(parent) = self.0.parent.clone() {
4747
48 pub fn contains_key(&self, key: &IStr) -> bool {48 pub fn contains_key(&self, key: &IStr) -> bool {
49 (self.0).current.contains_key(key)49 (self.0).current.contains_key(key)
50 || self50 || self.0.parent.as_ref().is_some_and(|p| p.contains_key(key))
51 .0
52 .parent
53 .as_ref()
54 .map_or(false, |p| p.contains_key(key))
55 }51 }
56}52}
5753
modifiedcrates/jrsonnet-evaluator/src/obj/mod.rsdiffbeforeafterboth
1use std::{1use std::{
2 any::Any,2 any::Any,
3 cell::{Cell, RefCell},3 cell::{Cell, RefCell},
4 clone::Clone,
4 collections::hash_map::Entry,5 collections::hash_map::Entry,
5 fmt::{self, Debug},6 fmt::{self, Debug},
6 hash::{Hash, Hasher},7 hash::{Hash, Hasher},
272273
273impl ObjValue {274impl ObjValue {
274 pub fn empty() -> Self {275 pub fn empty() -> Self {
275 EMPTY_OBJ.with(|v| v.clone())276 EMPTY_OBJ.with(Clone::clone)
276 }277 }
277 pub fn is_empty(&self) -> bool {278 pub fn is_empty(&self) -> bool {
278 self.0.cores.is_empty() || self.len() == 0279 self.0.cores.is_empty() || self.len() == 0
306 return Ok(GetFor::NotFound);307 return Ok(GetFor::NotFound);
307 }308 }
308 let v = self.this.get_idx(key, self.sup)?;309 let v = self.this.get_idx(key, self.sup)?;
309 Ok(v.map_or(GetFor::NotFound, |v| GetFor::Final(v)))310 Ok(v.map_or(GetFor::NotFound, GetFor::Final))
310 }311 }
311312
312 fn field_visibility_core(&self, field: IStr) -> FieldVisibility {313 fn field_visibility_core(&self, field: IStr) -> FieldVisibility {
313 match self.this.field_visibility_idx(field, self.sup) {314 self.this
315 .field_visibility_idx(field, self.sup)
314 Some(c) => FieldVisibility::Found(c),316 .map_or(FieldVisibility::NotFound, FieldVisibility::Found)
315 None => FieldVisibility::NotFound,
316 }
317 }317 }
318318
319 fn run_assertions_core(&self, _sup_this: SupThis) -> Result<()> {319 fn run_assertions_core(&self, _sup_this: SupThis) -> Result<()> {
modifiedcrates/jrsonnet-evaluator/src/obj/oop.rsdiffbeforeafterboth
1use std::cell::Cell;1use std::cell::{Cell, RefCell};
2use std::ops::ControlFlow;2use std::ops::ControlFlow;
3use std::{fmt, mem};3use std::{fmt, mem};
44
105105
106 fn run_assertions_core(&self, sup_this: SupThis) -> Result<()> {106 fn run_assertions_core(&self, sup_this: SupThis) -> Result<()> {
107 if let Some(assertion) = &self.assertion {107 if let Some(assertion) = &self.assertion {
108 assertion.0.run(sup_this.clone())?;108 assertion.0.run(sup_this)?;
109 }109 }
110 Ok(())110 Ok(())
111 }111 }
196 ObjValue(Cc::new(ObjValueInner {196 ObjValue(Cc::new(ObjValueInner {
197 cores: self.sup,197 cores: self.sup,
198 assertions_ran: Cell::new(false),198 assertions_ran: Cell::new(false),
199 value_cache: Default::default(),199 value_cache: RefCell::default(),
200 }))200 }))
201 }201 }
202}202}
modifiedcrates/jrsonnet-evaluator/src/stack.rsdiffbeforeafterboth
17 }17 }
18}18}
19#[cfg(not(nightly))]19#[cfg(not(nightly))]
20#[allow(dead_code)]
20type NightlyLocalKey<T> = std::thread::LocalKey<T>;21type NightlyLocalKey<T> = std::thread::LocalKey<T>;
2122
22#[cfg(nightly)]23#[cfg(nightly)]
60pub struct StackDepthGuard(PhantomData<()>);61pub struct StackDepthGuard(PhantomData<()>);
61impl Drop for StackDepthGuard {62impl Drop for StackDepthGuard {
62 fn drop(&mut self) {63 fn drop(&mut self) {
63 STACK_LIMIT.with(|limit| limit.current_depth.set(limit.current_depth.get() - 1))64 STACK_LIMIT.with(|limit| limit.current_depth.set(limit.current_depth.get() - 1));
64 }65 }
65}66}
6667
modifiedcrates/jrsonnet-evaluator/src/stdlib/format.rsdiffbeforeafterboth
297const NUMBERS: &[u8] = b"0123456789abcdefghijklmnopqrstuvwxyz";297const NUMBERS: &[u8] = b"0123456789abcdefghijklmnopqrstuvwxyz";
298298
299#[inline]299#[inline]
300#[allow(clippy::fn_params_excessive_bools)]
300pub fn render_integer(301pub fn render_integer(
301 out: &mut String,302 out: &mut String,
302 neg: bool,303 neg: bool,
330331
331 let pref_len = zero_prefix.len() as u16;332 let pref_len = zero_prefix.len() as u16;
332 let zp2 = zp333 let zp2 = zp
333 .saturating_sub(if !prefix_in_padding { pref_len } else { 0 })334 .saturating_sub(if prefix_in_padding { 0 } else { pref_len })
334 .max(precision)335 .max(precision)
335 .saturating_sub(if prefix_in_padding { pref_len } else { 0 } + digits.len() as u16);336 .saturating_sub(if prefix_in_padding { pref_len } else { 0 } + digits.len() as u16);
336337
369 out, neg, iv, padding, precision, blank, sign, 10, "", false, false,370 out, neg, iv, padding, precision, blank, sign, 10, "", false, false,
370 );371 );
371}372}
373#[allow(clippy::fn_params_excessive_bools)]
372pub fn render_octal(374pub fn render_octal(
373 out: &mut String,375 out: &mut String,
374 neg: bool,376 neg: bool,
439 // Note that it can also be equal to 10**prec and we'll need to carry441 // Note that it can also be equal to 10**prec and we'll need to carry
440 // over to the wholes. We operate on the absolute numbers, so that we442 // over to the wholes. We operate on the absolute numbers, so that we
441 // don't have trouble with the rounding direction.443 // don't have trouble with the rounding direction.
442 let denominator = 10.0f64.powi(precision as i32);444 let denominator = 10.0f64.powi(i32::from(precision));
443 let numerator = n.abs() * denominator + 0.5;445 let numerator = n.abs().mul_add(denominator, 0.5);
444 let whole = (numerator / denominator).floor();446 let whole = (numerator / denominator).floor();
445 let frac = numerator.floor() % denominator;447 let frac = numerator.floor() % denominator;
446448
611 } else {613 } else {
612 value.abs().log10().floor()614 value.abs().log10().floor()
613 };615 };
614 if exponent < -4.0 || exponent >= fpprec as f64 {616 if exponent < -4.0 || exponent >= f64::from(fpprec) {
615 render_float_sci(617 render_float_sci(
616 &mut tmp_out,618 &mut tmp_out,
617 value,619 value,
661 }663 }
662 },664 },
663 ConvTypeV::Percent => tmp_out.push('%'),665 ConvTypeV::Percent => tmp_out.push('%'),
664 };666 }
665667
666 let padding = width.saturating_sub(tmp_out.len() as u16);668 let padding = width.saturating_sub(tmp_out.len() as u16);
667669
modifiedcrates/jrsonnet-evaluator/src/tla.rsdiffbeforeafterboth
1use std::{collections::HashMap, hash::BuildHasher};
2
1use jrsonnet_interner::IStr;3use jrsonnet_interner::IStr;
2use jrsonnet_parser::Source;4use jrsonnet_parser::Source;
3use rustc_hash::FxHashMap;
45
5use crate::{6use crate::{
6 function::{CallLocation, TlaArg},7 function::{CallLocation, TlaArg},
7 in_description_frame, with_state, Result, Val,8 in_description_frame, with_state, Result, Val,
8};9};
910
10pub fn apply_tla(args: &FxHashMap<IStr, TlaArg>, val: Val) -> Result<Val> {11pub fn apply_tla<H: BuildHasher>(args: &HashMap<IStr, TlaArg, H>, val: Val) -> Result<Val> {
11 Ok(if let Val::Func(func) = val {12 Ok(if let Val::Func(func) = val {
12 in_description_frame(13 in_description_frame(
13 || "during TLA call".to_owned(),14 || "during TLA call".to_owned(),
modifiedcrates/jrsonnet-evaluator/src/typed/conversions.rsdiffbeforeafterboth
462 };462 };
463 if let Some(bytes) = a.as_any().downcast_ref::<BytesArray>() {463 if let Some(bytes) = a.as_any().downcast_ref::<BytesArray>() {
464 return Ok(bytes.0.as_slice().into());464 return Ok(bytes.0.as_slice().into());
465 };465 }
466 <Self as Typed>::TYPE.check(&value)?;466 <Self as Typed>::TYPE.check(&value)?;
467 // Any::downcast_ref::<ByteArray>(&a);467 // Any::downcast_ref::<ByteArray>(&a);
468 let mut out = Vec::with_capacity(a.len());468 let mut out = Vec::with_capacity(a.len());
modifiedcrates/jrsonnet-evaluator/src/val.rsdiffbeforeafterboth
65 MemoizedClusureThunkInner::Errored(e) => return Err(e.clone()),65 MemoizedClusureThunkInner::Errored(e) => return Err(e.clone()),
66 MemoizedClusureThunkInner::Pending => return Err(InfiniteRecursionDetected.into()),66 MemoizedClusureThunkInner::Pending => return Err(InfiniteRecursionDetected.into()),
67 MemoizedClusureThunkInner::Waiting { .. } => (),67 MemoizedClusureThunkInner::Waiting { .. } => (),
68 };68 }
69 let MemoizedClusureThunkInner::Waiting { env, closure } = replace(69 let MemoizedClusureThunkInner::Waiting { env, closure } = replace(
70 &mut *self.0.borrow_mut(),70 &mut *self.0.borrow_mut(),
71 MemoizedClusureThunkInner::Pending,71 MemoizedClusureThunkInner::Pending,
288 Self::Str(s) => {288 Self::Str(s) => {
289 let mut computed_len = None;289 let mut computed_len = None;
290 let mut get_len = || {290 let mut get_len = || {
291 computed_len.map_or_else(291 computed_len.unwrap_or_else(|| {
292 || {
293 let len = s.chars().count();292 let len = s.chars().count();
294 let _ = computed_len.insert(len);293 let _ = computed_len.insert(len);
295 len294 len
296 },295 })
297 |len| len,
298 )
299 };296 };
300 let mut get_idx = |pos: Option<i32>, default| {297 let mut get_idx = |pos: Option<i32>, default| {
446 pub const fn get(&self) -> f64 {443 pub const fn get(&self) -> f64 {
447 self.0444 self.0
448 }445 }
449 pub(crate) fn truncate_for_bitwise(&self) -> Result<i64> {446 pub(crate) fn truncate_for_bitwise(self) -> Result<i64> {
450 if self.0 < MIN_SAFE_INTEGER || self.0 > MAX_SAFE_INTEGER {447 if self.0 < MIN_SAFE_INTEGER || self.0 > MAX_SAFE_INTEGER {
451 bail!("numberic value outside of safe integer range for bitwise operation");448 bail!("numberic value outside of safe integer range for bitwise operation");
452 }449 }
modifiedcrates/jrsonnet-interner/src/lib.rsdiffbeforeafterboth
227type PoolMap = HashMap<Inner, (), FxBuildHasher>;227type PoolMap = HashMap<Inner, (), FxBuildHasher>;
228228
229thread_local! {229thread_local! {
230 static POOL: RefCell<PoolMap> = RefCell::new(HashMap::with_capacity_and_hasher(200, FxBuildHasher::default()));230 static POOL: RefCell<PoolMap> = RefCell::new(HashMap::with_capacity_and_hasher(200, FxBuildHasher));
231}231}
232232
233/// Utils for embedding jrsonnet in non-rust.
234///
233/// Jrsonnet golang bindings require that it is possible to move jsonnet235/// Jrsonnet golang bindings require that it is possible to move jsonnet
234/// VM between OS threads, and this is not possible due to usage of236/// VM between OS threads, and this is not possible due to usage of
235/// `thread_local`. Instead, there is two methods added, one should be237/// `thread_local`. Instead, there is two methods added, one should be
modifiedcrates/jrsonnet-macros/src/lib.rsdiffbeforeafterboth
127 Default(Expr),127 Default(Expr),
128}128}
129129
130#[allow(clippy::large_enum_variant, reason = "this macro is not that hot for it to matter")]
130enum ArgInfo {131enum ArgInfo {
131 Normal {132 Normal {
132 ty: Box<Type>,133 ty: Box<Type>,
modifiedcrates/jrsonnet-parser/src/expr.rsdiffbeforeafterboth
166 pub fn len(&self) -> usize {166 pub fn len(&self) -> usize {
167 self.exprs.len()167 self.exprs.len()
168 }168 }
169 pub fn is_empty(&self) -> bool {
170 self.exprs.is_empty()
171 }
172
169 pub fn binds_len(&self) -> usize {173 pub fn binds_len(&self) -> usize {
170 self.binds_len174 self.binds_len
modifiedcrates/jrsonnet-stdlib/src/arrays.rsdiffbeforeafterboth
98 for c in str.chars() {98 for c in str.chars() {
99 match func(Either2::A(c.to_string()))? {99 match func(Either2::A(c.to_string()))? {
100 Val::Str(o) => write!(out, "{o}").unwrap(),100 Val::Str(o) => write!(out, "{o}").unwrap(),
101 Val::Null => continue,101 Val::Null => {},
102 _ => bail!("in std.join all items should be strings"),102 _ => bail!("in std.join all items should be strings"),
103 };103 }
104 }104 }
105 Ok(IndexableVal::Str(out.into()))105 Ok(IndexableVal::Str(out.into()))
106 }106 }
114 out.push(oe?);114 out.push(oe?);
115 }115 }
116 }116 }
117 Val::Null => continue,117 Val::Null => {},
118 _ => bail!("in std.join all items should be arrays"),118 _ => bail!("in std.join all items should be arrays"),
119 };119 }
120 }120 }
121 Ok(IndexableVal::Arr(out.into()))121 Ok(IndexableVal::Arr(out.into()))
122 }122 }
205 out.push(item?);205 out.push(item?);
206 }206 }
207 } else if matches!(item, Val::Null) {207 } else if matches!(item, Val::Null) {
208 continue;
209 } else {208 } else {
210 bail!("in std.join all items should be arrays");209 bail!("in std.join all items should be arrays");
211 }210 }
226 first = false;225 first = false;
227 write!(out, "{item}").unwrap();226 write!(out, "{item}").unwrap();
228 } else if matches!(item, Val::Null) {227 } else if matches!(item, Val::Null) {
229 continue;
230 } else {228 } else {
231 bail!("in std.join all items should be strings");229 bail!("in std.join all items should be strings");
232 }230 }
modifiedcrates/jrsonnet-stdlib/src/manifest/xml.rsdiffbeforeafterboth
46 };46 };
47 if arr.is_empty() {47 if arr.is_empty() {
48 bail!("JSONML value should have tag (array length should be >=1)");48 bail!("JSONML value should have tag (array length should be >=1)");
49 };49 }
50 let tag = String::from_untyped(50 let tag = String::from_untyped(
51 arr.get(0)51 arr.get(0)
52 .description("getting JSONML tag")?52 .description("getting JSONML tag")?
modifiedcrates/jrsonnet-stdlib/src/manifest/yaml.rsdiffbeforeafterboth
90 RESERVED.iter().any(|k| key.eq_ignore_ascii_case(k))90 RESERVED.iter().any(|k| key.eq_ignore_ascii_case(k))
91 }91 }
9292
93 #[allow(clippy::if_same_then_else)]
93 // Check for unsafe characters94 // Check for unsafe characters
94 if !key95 if !key
95 .chars()96 .chars()
98 return false;99 return false;
99 }100 }
100 // Check for reserved words101 // Check for reserved words
101 if is_reserved(key) {102 else if is_reserved(key) {
102 return false;103 return false;
103 }104 }
104 // Check for timestamp values. Since spaces and colons are already forbidden,105 // Check for timestamp values. Since spaces and colons are already forbidden,
107 // - all characters match [0-9\-]108 // - all characters match [0-9\-]
108 // - has exactly 2 dashes109 // - has exactly 2 dashes
109 // are considered dates.110 // are considered dates.
110 if key.chars().all(|v| matches!(v, '0'..='9' | '-')) && count_char(key, '-') == 2 {111 else if key.chars().all(|v| matches!(v, '0'..='9' | '-')) && count_char(key, '-') == 2 {
111 return false;112 return false;
112 }113 }
113 // Check for integers. Keys that meet all of the following:114 // Check for integers. Keys that meet all of the following:
modifiedcrates/jrsonnet-stdlib/src/misc.rsdiffbeforeafterboth
172 let Some(patch) = patch.as_obj() else {172 let Some(patch) = patch.as_obj() else {
173 return Ok(patch);173 return Ok(patch);
174 };174 };
175 let target = target.as_obj().unwrap_or_else(|| ObjValue::empty());175 let target = target.as_obj().unwrap_or_else(ObjValue::empty);
176 let target_fields = target176 let target_fields = target
177 .fields(177 .fields(
178 // FIXME: Makes no sense to preserve order for BTreeSet, it would be better to use IndexSet here?178 // FIXME: Makes no sense to preserve order for BTreeSet, it would be better to use IndexSet here?
modifiedcrates/jrsonnet-stdlib/src/sets.rsdiffbeforeafterboth
21 let x = keyF(x)?;21 let x = keyF(x)?;
2222
23 while low < high {23 while low < high {
24 let middle = (high + low) / 2;24 let middle = usize::midpoint(high, low);
25 let comp = keyF(arr.get_lazy(middle).expect("in bounds"))?;25 let comp = keyF(arr.get_lazy(middle).expect("in bounds"))?;
26 match evaluate_compare_op(&comp, &x, BinaryOpType::Lt)? {26 match evaluate_compare_op(&comp, &x, BinaryOpType::Lt)? {
27 Ordering::Less => low = middle + 1,27 Ordering::Less => low = middle + 1,
66 bv = b.next();66 bv = b.next();
67 bk = bv.map(keyF).transpose()?;67 bk = bv.map(keyF).transpose()?;
68 }68 }
69 };69 }
70 }70 }
71 Ok(ArrValue::lazy(out))71 Ok(ArrValue::lazy(out))
72}72}
106 bv = b.next();106 bv = b.next();
107 bk = bv.map(keyF).transpose()?;107 bk = bv.map(keyF).transpose()?;
108 }108 }
109 };109 }
110 }110 }
111 while let Some(_ac) = &ak {111 while let Some(_ac) = &ak {
112 // In a, but not in b112 // In a, but not in b
154 bv = b.next();154 bv = b.next();
155 bk = bv.clone().map(keyF).transpose()?;155 bk = bv.clone().map(keyF).transpose()?;
156 }156 }
157 };157 }
158 }158 }
159 // a.len() > b.len()159 // a.len() > b.len()
160 while let Some(_ac) = &ak {160 while let Some(_ac) = &ak {
modifiedcrates/jrsonnet-stdlib/src/sort.rsdiffbeforeafterboth
66 return Err(err);66 return Err(err);
67 }67 }
68 }68 }
69 };69 }
70 Ok(values)70 Ok(values)
71}71}
7272
107 return Err(err);107 return Err(err);
108 }108 }
109 }109 }
110 };110 }
111 Ok(vk.into_iter().map(|v| v.0).collect())111 Ok(vk.into_iter().map(|v| v.0).collect())
112}112}
113113
204 }204 }
205}205}
206206
207fn eval_keyf(val: Val, key_f: &Option<FuncVal>) -> Result<Val> {207fn eval_keyf(val: Val, key_f: Option<&FuncVal>) -> Result<Val> {
208 if let Some(key_f) = key_f {208 if let Some(key_f) = key_f {
209 key_f.evaluate_simple(&(val,), false)209 key_f.evaluate_simple(&(val,), false)
210 } else {210 } else {
211 Ok(val)211 Ok(val)
212 }212 }
213}213}
214214
215fn array_top1(arr: ArrValue, key_f: Option<FuncVal>, ordering: Ordering) -> Result<Val> {215fn array_top1(arr: ArrValue, key_f: Option<&FuncVal>, ordering: Ordering) -> Result<Val> {
216 let mut iter = arr.iter();216 let mut iter = arr.iter();
217 let mut min = iter.next().expect("not empty")?;217 let mut min = iter.next().expect("not empty")?;
218 let mut min_key = eval_keyf(min.clone(), &key_f)?;218 let mut min_key = eval_keyf(min.clone(), key_f)?;
219 for item in iter {219 for item in iter {
220 let cur = item?;220 let cur = item?;
221 let cur_key = eval_keyf(cur.clone(), &key_f)?;221 let cur_key = eval_keyf(cur.clone(), key_f)?;
222 if evaluate_compare_op(&cur_key, &min_key, BinaryOpType::Lt)? == ordering {222 if evaluate_compare_op(&cur_key, &min_key, BinaryOpType::Lt)? == ordering {
223 min = cur;223 min = cur;
224 min_key = cur_key;224 min_key = cur_key;
236 if arr.is_empty() {236 if arr.is_empty() {
237 return eval_on_empty(onEmpty);237 return eval_on_empty(onEmpty);
238 }238 }
239 array_top1(arr, keyF, Ordering::Less)239 array_top1(arr, keyF.as_ref(), Ordering::Less)
240}240}
241#[builtin]241#[builtin]
242pub fn builtin_max_array(242pub fn builtin_max_array(
247 if arr.is_empty() {247 if arr.is_empty() {
248 return eval_on_empty(onEmpty);248 return eval_on_empty(onEmpty);
249 }249 }
250 array_top1(arr, keyF, Ordering::Greater)250 array_top1(arr, keyF.as_ref(), Ordering::Greater)
251}251}
252252
modifiedcrates/jrsonnet-stdlib/src/strings.rsdiffbeforeafterboth
5353
54#[builtin]54#[builtin]
55pub fn builtin_equals_ignore_case(str1: String, str2: String) -> bool {55pub fn builtin_equals_ignore_case(str1: String, str2: String) -> bool {
56 str1.to_ascii_lowercase() == str2.to_ascii_lowercase()56 str1.eq_ignore_ascii_case(&str2)
57}57}
5858
59#[builtin]59#[builtin]
modifiedcrates/jrsonnet-types/src/lib.rsdiffbeforeafterboth
133 Self::Sum(v) => write_union(f, false, v.iter())?,133 Self::Sum(v) => write_union(f, false, v.iter())?,
134 Self::SumRef(v) => write_union(f, false, v.iter().copied())?,134 Self::SumRef(v) => write_union(f, false, v.iter().copied())?,
135 Self::Lazy(lazy) => write!(f, "Lazy<{lazy}>")?,135 Self::Lazy(lazy) => write!(f, "Lazy<{lazy}>")?,
136 };136 }
137 Ok(())137 Ok(())
138 }138 }
139}139}
modifiedtests/tests/common.rsdiffbeforeafterboth
57#[builtin]57#[builtin]
58fn param_names(fun: FuncVal) -> Vec<String> {58fn param_names(fun: FuncVal) -> Vec<String> {
59 fun.params()59 fun.params()
60 .into_iter()60 .iter()
61 .map(|v| v.name().as_str().unwrap_or("<unnamed>").to_owned())61 .map(|v| v.name().as_str().unwrap_or("<unnamed>").to_owned())
62 .collect()62 .collect()
63}63}
6464
65#[derive(Trace)]65#[derive(Trace)]
66#[allow(dead_code)]
66pub struct ContextInitializer;67pub struct ContextInitializer;
67impl ContextInitializerT for ContextInitializer {68impl ContextInitializerT for ContextInitializer {
68 fn populate(&self, _for_file: Source, builder: &mut ContextBuilder) {69 fn populate(&self, _for_file: Source, builder: &mut ContextBuilder) {
modifiedtests/tests/cpp_test_suite.rsdiffbeforeafterboth
23 // C++ test suite23 // C++ test suite
24 std_context.add_ext_str("var1".into(), "test".into());24 std_context.add_ext_str("var1".into(), "test".into());
25 std_context25 std_context
26 .add_ext_code("var2".into(), "{x:1,y:2}")26 .add_ext_code("var2", "{x:1,y:2}")
27 .expect("code is valid");27 .expect("code is valid");
2828
29 // Golang test suite29 // Golang test suite
30 std_context30 std_context
31 .add_ext_code("codeVar".into(), "3+3")31 .add_ext_code("codeVar", "3+3")
32 .expect("code is valid");32 .expect("code is valid");
33 std_context.add_ext_str("stringVar".into(), "2 + 2".into());33 std_context.add_ext_str("stringVar".into(), "2 + 2".into());
34 std_context34 std_context
35 .add_ext_code(35 .add_ext_code(
36 "selfRecursiveVar".into(),36 "selfRecursiveVar",
37 r#"[42, std.extVar("selfRecursiveVar")[0] + 1]"#,37 r#"[42, std.extVar("selfRecursiveVar")[0] + 1]"#,
38 )38 )
39 .expect("code is valid");39 .expect("code is valid");
40 std_context40 std_context
41 .add_ext_code(41 .add_ext_code(
42 "mutuallyRecursiveVar1".into(),42 "mutuallyRecursiveVar1",
43 r#"[42, std.extVar("mutuallyRecursiveVar2")[0] + 1]"#,43 r#"[42, std.extVar("mutuallyRecursiveVar2")[0] + 1]"#,
44 )44 )
45 .expect("code is valid");45 .expect("code is valid");
46 std_context46 std_context
47 .add_ext_code(47 .add_ext_code(
48 "mutuallyRecursiveVar2".into(),48 "mutuallyRecursiveVar2",
49 r#"[42, std.extVar("mutuallyRecursiveVar1")[0] + 1]"#,49 r#"[42, std.extVar("mutuallyRecursiveVar1")[0] + 1]"#,
50 )50 )
51 .expect("code is valid");51 .expect("code is valid");
203 let root = root_tests.join(root_dir);203 let root = root_tests.join(root_dir);
204 let root_override = root_tests.join(format!("{root_dir}_golden_override"));204 let root_override = root_tests.join(format!("{root_dir}_golden_override"));
205205
206 for entry in fs::read_dir(&root).map_err(|e| io::Error::new(ErrorKind::Other, format!("failed to enumerate cpp_test_suite dir (Note: it needs to be cloned from C++ jsonnet repo for this test): {e}")))? {206 for entry in fs::read_dir(&root).map_err(|e| io::Error::other(format!("failed to enumerate cpp_test_suite dir (Note: it needs to be cloned from C++ jsonnet repo for this test): {e}")))? {
207 let entry = entry?;207 let entry = entry?;
208 if !entry.path().extension().map_or(false, |e| e == "jsonnet") {208 if entry.path().extension().is_none_or(|e| e != "jsonnet") {
209 continue;209 continue;
210 }210 }
211211
212 if entry212 if entry
213 .path()213 .path()
214 .file_name()214 .file_name()
215 .and_then(|v| v.to_str())215 .and_then(|v| v.to_str())
216 .map_or(false, |v| SKIPPED.contains(&v))216 .is_some_and(|v| SKIPPED.contains(&v))
217 {217 {
218 continue;218 continue;
219 }219 }
227 golden_path2.set_extension("golden");227 golden_path2.set_extension("golden");
228228
229 let golden_override =229 let golden_override =
230 root_override.join(&golden_path.file_name().expect("file has basename"));230 root_override.join(golden_path.file_name().expect("file has basename"));
231231
232 // .jsonnet.golden for C++ tests232 // .jsonnet.golden for C++ tests
233 let mut golden = read_file(&golden_path)?;233 let mut golden = read_file(&golden_path)?;
282 }282 }
283 }283 }
284 }284 }
285 };285 }
286 }286 }
287 }287 }
288288
modifiedtests/tests/golden.rsdiffbeforeafterboth
40#[test]40#[test]
41fn golden() {41fn golden() {
42 glob!("../", "golden/*.jsonnet", |path| {42 glob!("../", "golden/*.jsonnet", |path| {
43 let result = run(&path);43 let result = run(path);
4444
45 assert_snapshot!(result)45 assert_snapshot!(result);
46 });46 });
47}47}
4848
modifiedtests/tests/suite.rsdiffbeforeafterboth
32 file.display(),32 file.display(),
33 trace_format.format(&e).unwrap()33 trace_format.format(&e).unwrap()
34 ),34 ),
35 };35 }
36}36}
3737
38#[test]38#[test]
4242
43 for entry in fs::read_dir(&root)? {43 for entry in fs::read_dir(&root)? {
44 let entry = entry?;44 let entry = entry?;
45 if !entry.path().extension().map_or(false, |e| e == "jsonnet") {45 if entry.path().extension().is_some_and(|e| e == "jsonnet") {
46 continue;46 run(&entry.path());
47 }47 }
48
49 run(&entry.path());
50 }48 }
5149
52 Ok(())50 Ok(())