difftreelog
style fix formatting
in: master
31 files changed
crates/jrsonnet-evaluator/src/analyze.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/analyze.rs
+++ b/crates/jrsonnet-evaluator/src/analyze.rs
@@ -21,10 +21,10 @@
use jrsonnet_gcmodule::Acyclic;
use jrsonnet_interner::IStr;
use jrsonnet_ir::{
- function::FunctionSignature, ArgsDesc, AssertExpr, AssertStmt, BinaryOp, BinaryOpType,
- BindSpec, CompSpec, Destruct, Expr, ExprParams, FieldName, ForSpecData, IfElse, IfSpecData,
- ImportKind, LiteralType, NumValue, ObjBody, ObjComp, ObjMembers, Slice, SliceDesc, Span,
- Spanned, UnaryOpType, Visibility,
+ ArgsDesc, AssertExpr, AssertStmt, BinaryOp, BinaryOpType, BindSpec, CompSpec, Destruct, Expr,
+ ExprParams, FieldName, ForSpecData, IfElse, IfSpecData, ImportKind, LiteralType, NumValue,
+ ObjBody, ObjComp, ObjMembers, Slice, SliceDesc, Span, Spanned, UnaryOpType, Visibility,
+ function::FunctionSignature,
};
use rustc_hash::FxHashMap;
use smallvec::SmallVec;
crates/jrsonnet-evaluator/src/arr/mod.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/arr/mod.rs
+++ b/crates/jrsonnet-evaluator/src/arr/mod.rs
@@ -5,9 +5,9 @@
rc::Rc,
};
-use jrsonnet_gcmodule::{cc_dyn, Cc};
+use jrsonnet_gcmodule::{Cc, cc_dyn};
-use crate::{analyze::LExpr, function::NativeFn, typed::IntoUntyped, Context, Result, Thunk, Val};
+use crate::{Context, Result, Thunk, Val, analyze::LExpr, function::NativeFn, typed::IntoUntyped};
mod spec;
pub use spec::{ArrayLike, *};
crates/jrsonnet-evaluator/src/arr/spec.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/arr/spec.rs
+++ b/crates/jrsonnet-evaluator/src/arr/spec.rs
@@ -11,13 +11,13 @@
use super::ArrValue;
use crate::{
+ Context, Error, ObjValue, Result, Thunk, Val,
analyze::LExpr,
error::ErrorKind::InfiniteRecursionDetected,
evaluate::evaluate,
function::NativeFn,
typed::{IntoUntyped, Typed},
val::ThunkValue,
- Context, Error, ObjValue, Result, Thunk, Val,
};
pub trait ArrayLike: Any + Trace + Debug {
crates/jrsonnet-evaluator/src/ctx.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/ctx.rs
+++ b/crates/jrsonnet-evaluator/src/ctx.rs
@@ -4,7 +4,7 @@
use jrsonnet_gcmodule::{Cc, Trace};
use jrsonnet_interner::IStr;
-use crate::{analyze::LocalId, error, error::ErrorKind::*, Pending, Result, SupThis, Thunk, Val};
+use crate::{Pending, Result, SupThis, Thunk, Val, analyze::LocalId, error, error::ErrorKind::*};
#[derive(Debug, Trace, Clone, Educe)]
#[educe(PartialEq)]
crates/jrsonnet-evaluator/src/error.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/error.rs
+++ b/crates/jrsonnet-evaluator/src/error.rs
@@ -9,10 +9,10 @@
use thiserror::Error;
use crate::{
+ ObjValue, ResolvePathOwned,
function::{CallLocation, FunctionSignature, ParamName},
stdlib::format::FormatError,
typed::TypeLocError,
- ObjValue, ResolvePathOwned,
};
#[derive(Debug, Clone, Acyclic)]
@@ -286,11 +286,11 @@
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- writeln!(f, "{}", self.0 .0)?;
- for el in &self.0 .1 .0 {
+ writeln!(f, "{}", self.0.0)?;
+ for el in &self.0.1.0 {
write!(f, "\t{}", el.desc)?;
if let Some(loc) = &el.location {
- write!(f, "at {}", loc.0 .0 .0)?;
+ write!(f, "at {}", loc.0.0.0)?;
loc.0.map_source_locations(&[loc.1, loc.2]);
}
writeln!(f)?;
crates/jrsonnet-evaluator/src/evaluate/compspec.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/evaluate/compspec.rs
+++ b/crates/jrsonnet-evaluator/src/evaluate/compspec.rs
@@ -7,12 +7,12 @@
evaluate_field_member_static, evaluate_field_member_unbound,
};
use crate::{
+ Context, ContextBuilder, ObjValue, ObjValueBuilder, Pending, Result, Thunk, Val,
analyze::{LArrComp, LBind, LCompSpec, LDestruct, LExpr, LFieldMember, LObjComp, LocalId},
arr::ArrValue,
bail,
error::ErrorKind::*,
evaluate::evaluate,
- Context, ContextBuilder, ObjValue, ObjValueBuilder, Pending, Result, Thunk, Val,
};
trait CompCollector {
crates/jrsonnet-evaluator/src/evaluate/destructure.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/evaluate/destructure.rs
+++ b/crates/jrsonnet-evaluator/src/evaluate/destructure.rs
@@ -3,10 +3,10 @@
use jrsonnet_gcmodule::Trace;
use crate::{
+ Context, ContextBuilder, Pending, Result, SupThis, Thunk, Unbound, Val,
analyze::{LBind, LDestruct, LDestructField, LDestructRest, LExpr, LocalId},
bail,
evaluate::evaluate,
- Context, ContextBuilder, Pending, Result, SupThis, Thunk, Unbound, Val,
};
#[allow(dead_code, reason = "not dead in exp-destruct")]
@@ -97,7 +97,7 @@
use jrsonnet_interner::IStr;
use rustc_hash::FxHashSet;
- use crate::{bail, ObjValueBuilder};
+ use crate::{ObjValueBuilder, bail};
let captured_fields: FxHashSet<IStr> = fields.iter().map(|f| f.name.clone()).collect();
let field_names: Vec<(IStr, bool)> = fields
crates/jrsonnet-evaluator/src/evaluate/mod.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/evaluate/mod.rs
+++ b/crates/jrsonnet-evaluator/src/evaluate/mod.rs
@@ -11,19 +11,20 @@
operator::evaluate_binary_op_special,
};
use crate::{
+ Context, Error, ObjValue, ObjValueBuilder, ObjectAssertion, Result, ResultExt as _, SupThis,
+ Unbound, Val,
analyze::{
LArgsDesc, LAssertStmt, LExpr, LFieldMember, LFieldName, LFunction, LIndexPart, LObjBody,
LObjMembers,
},
bail,
- error::{suggest_object_fields, ErrorKind::*},
+ error::{ErrorKind::*, suggest_object_fields},
evaluate::operator::evaluate_unary_op,
- function::{prepared::PreparedFuncVal, CallLocation, FuncDesc, FuncVal},
+ function::{CallLocation, FuncDesc, FuncVal, prepared::PreparedFuncVal},
in_frame, runtime_error,
typed::FromUntyped as _,
val::{CachedUnbound, Thunk},
- with_state, Context, Error, ObjValue, ObjValueBuilder, ObjectAssertion, Result, ResultExt as _,
- SupThis, Unbound, Val,
+ with_state,
};
pub mod compspec;
crates/jrsonnet-evaluator/src/evaluate/operator.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/evaluate/operator.rs
+++ b/crates/jrsonnet-evaluator/src/evaluate/operator.rs
@@ -3,6 +3,7 @@
use jrsonnet_ir::{BinaryOpType, UnaryOpType};
use crate::{
+ Context, Result, Val,
analyze::LExpr,
arr::ArrValue,
bail, error,
@@ -10,8 +11,7 @@
evaluate::evaluate,
stdlib::std_format,
typed::IntoUntyped as _,
- val::{equals, StrValue},
- Context, Result, Val,
+ val::{StrValue, equals},
};
pub fn evaluate_unary_op(op: UnaryOpType, b: &Val) -> Result<Val> {
crates/jrsonnet-evaluator/src/function/mod.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/function/mod.rs
+++ b/crates/jrsonnet-evaluator/src/function/mod.rs
@@ -8,13 +8,13 @@
use self::{
builtin::Builtin,
- prepared::{parse_prepared_builtin_call, PreparedCall},
+ prepared::{PreparedCall, parse_prepared_builtin_call},
};
use crate::{
+ Context, ContextBuilder, Result, Thunk, Val,
analyze::{LDestruct, LExpr, LFunction},
evaluate::{destructure::destruct, ensure_sufficient_stack, evaluate, evaluate_trivial},
function::builtin::BuiltinFunc,
- Context, ContextBuilder, Result, Thunk, Val,
};
pub mod builtin;
@@ -210,8 +210,7 @@
return false;
}
#[allow(irrefutable_let_patterns, reason = "refutable with exp-destruct")]
- let LDestruct::Full(id) = ¶m.destruct
- else {
+ let LDestruct::Full(id) = ¶m.destruct else {
return false;
};
matches!(&*desc.func.body, LExpr::Local(v) if v == id)
crates/jrsonnet-evaluator/src/function/parse.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/function/parse.rs
+++ b/crates/jrsonnet-evaluator/src/function/parse.rs
@@ -1,9 +1,9 @@
use std::rc::Rc;
use crate::{
+ Context, ContextBuilder, Result, Thunk,
analyze::LFunction,
evaluate::{destructure::destruct, evaluate},
- Context, ContextBuilder, Result, Thunk,
};
/// Creates Context with all argument default values applied
crates/jrsonnet-evaluator/src/function/prepared.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/function/prepared.rs
+++ b/crates/jrsonnet-evaluator/src/function/prepared.rs
@@ -5,10 +5,7 @@
use rustc_hash::FxHashSet;
use super::{CallLocation, FuncVal};
-use crate::{
- Result, Thunk, Val, bail,
- error::ErrorKind::*,
-};
+use crate::{Result, Thunk, Val, bail, error::ErrorKind::*};
#[derive(Debug, Trace, Clone)]
pub struct PreparedFuncVal {
crates/jrsonnet-evaluator/src/integrations/serde.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/integrations/serde.rs
+++ b/crates/jrsonnet-evaluator/src/integrations/serde.rs
@@ -3,16 +3,16 @@
use jrsonnet_interner::{IBytes, IStr};
use jrsonnet_ir::NumValue;
use serde::{
+ Deserialize, Serialize, Serializer,
de::{self, Visitor},
ser::{
Error, SerializeMap, SerializeSeq, SerializeStruct, SerializeStructVariant, SerializeTuple,
SerializeTupleStruct, SerializeTupleVariant,
},
- Deserialize, Serialize, Serializer,
};
use crate::{
- in_description_frame, runtime_error, Error as JrError, ObjValue, ObjValueBuilder, Result, Val,
+ Error as JrError, ObjValue, ObjValueBuilder, Result, Val, in_description_frame, runtime_error,
};
impl<'de> Deserialize<'de> for Val {
crates/jrsonnet-evaluator/src/lib.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/lib.rs
+++ b/crates/jrsonnet-evaluator/src/lib.rs
@@ -39,7 +39,7 @@
pub use evaluate::ensure_sufficient_stack;
use function::CallLocation;
pub use import::*;
-use jrsonnet_gcmodule::{cc_dyn, Cc, Trace};
+use jrsonnet_gcmodule::{Cc, Trace, cc_dyn};
pub use jrsonnet_interner::{IBytes, IStr};
use jrsonnet_ir::Expr;
pub use jrsonnet_ir::{NumValue, Source, SourcePath, Span};
crates/jrsonnet-evaluator/src/manifest.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/manifest.rs
+++ b/crates/jrsonnet-evaluator/src/manifest.rs
@@ -1,8 +1,7 @@
use std::{borrow::Cow, fmt::Write, hint::black_box, ptr};
use crate::{
- bail, evaluate::ensure_sufficient_stack, in_description_frame, Error,
- Result, ResultExt, Val,
+ Error, Result, ResultExt, Val, bail, evaluate::ensure_sufficient_stack, in_description_frame,
};
pub trait ManifestFormat {
crates/jrsonnet-evaluator/src/obj/mod.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/obj/mod.rs
+++ b/crates/jrsonnet-evaluator/src/obj/mod.rs
@@ -11,8 +11,8 @@
};
use educe::Educe;
-use im_rc::{vector, Vector};
-use jrsonnet_gcmodule::{cc_dyn, Acyclic, Cc, Trace, Weak};
+use im_rc::{Vector, vector};
+use jrsonnet_gcmodule::{Acyclic, Cc, Trace, Weak, cc_dyn};
use jrsonnet_interner::IStr;
use jrsonnet_ir::Span;
use rustc_hash::{FxHashMap, FxHashSet};
@@ -23,13 +23,13 @@
pub use oop::ObjValueBuilder;
use crate::{
+ CcUnbound, MaybeUnbound, Result, Thunk, Unbound, Val,
arr::{PickObjectKeyValues, PickObjectValues},
bail,
- error::{suggest_object_fields, ErrorKind::*},
+ error::{ErrorKind::*, suggest_object_fields},
evaluate::operator::evaluate_add_op,
identity_hash,
val::{ArrValue, ThunkValue},
- CcUnbound, MaybeUnbound, Result, Thunk, Unbound, Val,
};
#[cfg(not(feature = "exp-preserve-order"))]
crates/jrsonnet-evaluator/src/trace/mod.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/trace/mod.rs
+++ b/crates/jrsonnet-evaluator/src/trace/mod.rs
@@ -10,7 +10,7 @@
#[cfg(feature = "explaining-traces")]
use jrsonnet_ir::Span;
-use crate::{error::ErrorKind, Error};
+use crate::{Error, error::ErrorKind};
/// The way paths should be displayed
#[derive(Clone, Trace)]
@@ -259,7 +259,7 @@
struct ResetData {
loc: Span,
}
- use hi_doc::{source_to_ansi, Formatting, SnippetBuilder, Text};
+ use hi_doc::{Formatting, SnippetBuilder, Text, source_to_ansi};
write!(out, "{}", error.error())?;
if let ErrorKind::ImportSyntaxError { path, error } = error.error() {
@@ -277,14 +277,15 @@
use crate::analyze::DiagLevel;
let mut builder: Option<SnippetBuilder> = None;
let mut current_src: Option<&str> = None;
- let flush =
- |builder: Option<SnippetBuilder>, out: &mut dyn std::fmt::Write| -> Result<(), std::fmt::Error> {
- if let Some(b) = builder {
- let ansi = source_to_ansi(&b.build());
- write!(out, "\n{}", ansi.trim_end())?;
- }
- Ok(())
- };
+ let flush = |builder: Option<SnippetBuilder>,
+ out: &mut dyn std::fmt::Write|
+ -> Result<(), std::fmt::Error> {
+ if let Some(b) = builder {
+ let ansi = source_to_ansi(&b.build());
+ write!(out, "\n{}", ansi.trim_end())?;
+ }
+ Ok(())
+ };
for diag in diagnostics {
if let Some(span) = &diag.span {
let src = span.0.code();
@@ -295,14 +296,12 @@
}
let b = builder.as_mut().unwrap();
let ab = match diag.level {
- DiagLevel::Error => b.error(Text::fragment(
- diag.message.clone(),
- Formatting::default(),
- )),
- DiagLevel::Warning => b.warning(Text::fragment(
- diag.message.clone(),
- Formatting::default(),
- )),
+ DiagLevel::Error => {
+ b.error(Text::fragment(diag.message.clone(), Formatting::default()))
+ }
+ DiagLevel::Warning => {
+ b.warning(Text::fragment(diag.message.clone(), Formatting::default()))
+ }
};
ab.range(span.range()).build();
} else {
crates/jrsonnet-evaluator/src/val.rsdiffbeforeafterboth1use std::{2 cell::RefCell,3 cmp::Ordering,4 fmt::{self, Debug, Display},5 marker::PhantomData,6 mem::replace,7 num::NonZeroU32,8 rc::Rc,9};1011use jrsonnet_gcmodule::{Acyclic, Cc, Trace, cc_dyn};12use jrsonnet_interner::IStr;13use jrsonnet_ir::BinaryOpType;14pub use jrsonnet_macros::Thunk;15use jrsonnet_types::ValType;16use rustc_hash::FxHashMap;1718pub use crate::arr::{ArrValue, ArrayLike};19use crate::{20 NumValue, ObjValue, Result, SupThis, Unbound, WeakSupThis, bail, error::{Error, ErrorKind::*}, evaluate::operator::{evaluate_compare_op, evaluate_mod_op}, function::FuncVal, gc::WithCapacityExt as _, manifest::{ManifestFormat, ToStringFormat}, typed::BoundedUsize21};2223pub trait ThunkValue: Trace {24 type Output;25 fn get(&self) -> Result<Self::Output>;26}2728#[derive(Trace)]29enum MemoizedClusureThunkInner<D: Trace, T: Trace> {30 Computed(T),31 Errored(Error),32 Waiting {33 env: D,34 // Carries no data, as it is not a real closure, all the35 // captured environment is stored in `env` field.36 #[trace(skip)]37 closure: fn(D) -> Result<T>,38 },39 Pending,40}41#[derive(Trace)]42pub struct MemoizedClosureThunk<D: Trace, T: Trace>(RefCell<MemoizedClusureThunkInner<D, T>>);43impl<D: Trace, T: Trace> MemoizedClosureThunk<D, T> {44 pub fn new(env: D, closure: fn(D) -> Result<T>) -> Self {45 Self(RefCell::new(MemoizedClusureThunkInner::Waiting {46 env,47 closure,48 }))49 }50}5152impl<D: Trace, T: Trace + Clone> ThunkValue for MemoizedClosureThunk<D, T> {53 type Output = T;5455 fn get(&self) -> Result<Self::Output> {56 match &*self.0.borrow() {57 MemoizedClusureThunkInner::Computed(v) => return Ok(v.clone()),58 MemoizedClusureThunkInner::Errored(e) => return Err(e.clone()),59 MemoizedClusureThunkInner::Pending => return Err(InfiniteRecursionDetected.into()),60 MemoizedClusureThunkInner::Waiting { .. } => (),61 }62 let MemoizedClusureThunkInner::Waiting { env, closure } = replace(63 &mut *self.0.borrow_mut(),64 MemoizedClusureThunkInner::Pending,65 ) else {66 unreachable!();67 };68 let new_value = match closure(env) {69 Ok(v) => v,70 Err(e) => {71 *self.0.borrow_mut() = MemoizedClusureThunkInner::Errored(e.clone());72 return Err(e);73 }74 };75 *self.0.borrow_mut() = MemoizedClusureThunkInner::Computed(new_value.clone());76 Ok(new_value)77 }78}7980cc_dyn!(81 /// Lazily evaluated value82 #[derive(Clone)] Thunk<V: Trace>,83 ThunkValue<Output = V>,84 pub fn new() {...}85);8687impl<T: Trace> Thunk<T> {88 pub fn evaluated(val: T) -> Self89 where90 T: Clone,91 {92 #[derive(Trace)]93 struct EvaluatedThunk<T: Trace>(T);94 impl<T> ThunkValue for EvaluatedThunk<T>95 where96 T: Clone + Trace,97 {98 type Output = T;99100 fn get(&self) -> Result<Self::Output> {101 Ok(self.0.clone())102 }103 }104 Self::new(EvaluatedThunk(val))105 }106 pub fn errored(e: Error) -> Self {107 #[derive(Trace)]108 struct ErroredThunk<T: Trace>(Error, PhantomData<T>);109 impl<T> ThunkValue for ErroredThunk<T>110 where111 T: Trace,112 {113 type Output = T;114115 fn get(&self) -> Result<Self::Output> {116 Err(self.0.clone())117 }118 }119 Self::new(ErroredThunk(e, PhantomData))120 }121 pub fn result(res: Result<T, Error>) -> Self122 where123 T: Clone,124 {125 match res {126 Ok(o) => Self::evaluated(o),127 Err(e) => Self::errored(e),128 }129 }130}131132impl<T> Thunk<T>133where134 T: Trace,135{136 pub fn force(&self) -> Result<()> {137 self.evaluate()?;138 Ok(())139 }140141 /// Evaluate thunk, or return cached value142 ///143 /// # Errors144 ///145 /// - Lazy value evaluation returned error146 /// - This method was called during inner value evaluation147 pub fn evaluate(&self) -> Result<T> {148 self.0.get()149 }150}151152pub trait ThunkMapper<Input>: Trace {153 type Output;154 fn map(self, from: Input) -> Result<Self::Output>;155}156impl<Input> Thunk<Input>157where158 Input: Trace,159{160 pub fn map<M>(self, mapper: M) -> Thunk<M::Output>161 where162 M: ThunkMapper<Input>,163 M::Output: Trace + Clone,164 {165 let inner = self;166 Thunk!(move || {167 let value = inner.evaluate()?;168 let mapped = mapper.map(value)?;169 Ok(mapped)170 })171 }172}173174impl<T: Trace + Clone> From<Result<T>> for Thunk<T> {175 fn from(value: Result<T>) -> Self {176 match value {177 Ok(o) => Self::evaluated(o),178 Err(e) => Self::errored(e),179 }180 }181}182impl<T, V: Trace> From<T> for Thunk<V>183where184 T: ThunkValue<Output = V>,185{186 fn from(value: T) -> Self {187 Self::new(value)188 }189}190191impl<T: Trace + Default + Clone> Default for Thunk<T> {192 fn default() -> Self {193 Self::evaluated(T::default())194 }195}196197#[derive(Trace, Clone)]198pub struct CachedUnbound<I, T>199where200 I: Unbound<Bound = T>,201 T: Trace,202{203 cache: Cc<RefCell<FxHashMap<WeakSupThis, T>>>,204 value: I,205}206impl<I: Unbound<Bound = T>, T: Trace> CachedUnbound<I, T> {207 pub fn new(value: I) -> Self {208 Self {209 cache: Cc::new(RefCell::new(FxHashMap::new())),210 value,211 }212 }213}214impl<I: Unbound<Bound = T>, T: Clone + Trace> Unbound for CachedUnbound<I, T> {215 type Bound = T;216 fn bind(&self, sup_this: SupThis) -> Result<T> {217 let cache_key = sup_this.clone().downgrade();218 {219 if let Some(t) = self.cache.borrow().get(&cache_key) {220 return Ok(t.clone());221 }222 }223 let bound = self.value.bind(sup_this)?;224225 {226 let mut cache = self.cache.borrow_mut();227 cache.insert(cache_key, bound.clone());228 }229230 Ok(bound)231 }232}233234impl<T: Debug + Trace> Debug for Thunk<T> {235 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {236 write!(f, "Lazy")237 }238}239impl<T: Trace> PartialEq for Thunk<T> {240 fn eq(&self, other: &Self) -> bool {241 Cc::ptr_eq(&self.0, &other.0)242 }243}244245/// Represents a Jsonnet value, which can be sliced or indexed (string or array).246#[allow(clippy::module_name_repetitions)]247pub enum IndexableVal {248 /// String.249 Str(IStr),250 /// Array.251 Arr(ArrValue),252}253impl IndexableVal {254 pub fn is_empty(&self) -> bool {255 match self {256 Self::Str(s) => s.is_empty(),257 Self::Arr(s) => s.is_empty(),258 }259 }260261 pub fn to_array(self) -> ArrValue {262 match self {263 Self::Str(s) => s.chars().collect(),264 Self::Arr(arr) => arr,265 }266 }267 /// Slice the value.268 ///269 /// # Implementation270 ///271 /// For strings, will create a copy of specified interval.272 ///273 /// For arrays, nothing will be copied on this call, instead [`ArrValue::Slice`] view will be returned.274 pub fn slice(275 self,276 index: Option<i32>,277 end: Option<i32>,278 step: Option<BoundedUsize<1, { i32::MAX as usize }>>,279 ) -> Result<Self> {280 match &self {281 Self::Str(s) => {282 let mut computed_len = None;283 let mut get_len = || {284 computed_len.unwrap_or_else(|| {285 let len = s.chars().count();286 let _ = computed_len.insert(len);287 len288 })289 };290 let mut get_idx = |pos: Option<i32>, default| {291 match pos {292 #[expect(clippy::cast_sign_loss, reason = "abs value is used")]293 Some(v) if v < 0 => get_len().saturating_sub((-v as isize) as usize),294 // No need to clamp, as iterator interface is used295 #[expect(clippy::cast_sign_loss, reason = "abs value is used")]296 Some(v) => v as usize,297 None => default,298 }299 };300301 let index = get_idx(index, 0);302 let end = get_idx(end, usize::MAX);303 let step = step.as_deref().copied().unwrap_or(1);304305 if index >= end {306 return Ok(Self::Str("".into()));307 }308309 Ok(Self::Str(310 (s.chars()311 .skip(index)312 .take(end - index)313 .step_by(step)314 .collect::<String>())315 .into(),316 ))317 }318 Self::Arr(arr) => Ok(Self::Arr(arr.clone().slice(319 index,320 end,321 #[expect(322 clippy::cast_possible_truncation,323 reason = "overflow will result with skip too large which would be equivalent"324 )]325 step.map(|v| NonZeroU32::new(v.value() as u32).expect("bounded != 0")),326 ))),327 }328 }329}330331#[derive(Debug, Clone, Acyclic)]332pub enum StrValue {333 Flat(IStr),334 Tree(Rc<(StrValue, StrValue, usize)>),335}336impl StrValue {337 pub fn concat(a: Self, b: Self) -> Self {338 // TODO: benchmark for an optimal value, currently just a arbitrary choice339 const STRING_EXTEND_THRESHOLD: usize = 100;340341 if a.is_empty() {342 b343 } else if b.is_empty() {344 a345 } else if a.len() + b.len() < STRING_EXTEND_THRESHOLD {346 Self::Flat(format!("{a}{b}").into())347 } else {348 let len = a.len() + b.len();349 Self::Tree(Rc::new((a, b, len)))350 }351 }352 pub fn chunks(&self, c: &mut impl FnMut(&IStr)) {353 fn write_buf(s: &StrValue, c: &mut impl FnMut(&IStr)) {354 match s {355 StrValue::Flat(f) => c(f),356 StrValue::Tree(t) => {357 write_buf(&t.0, c);358 write_buf(&t.1, c);359 }360 }361 }362 write_buf(self, c);363 }364 pub fn into_flat(&self) -> IStr {365 fn write_buf(s: &StrValue, out: &mut String) {366 match s {367 StrValue::Flat(f) => out.push_str(f),368 StrValue::Tree(t) => {369 write_buf(&t.0, out);370 write_buf(&t.1, out);371 }372 }373 }374 match self {375 Self::Flat(f) => f.clone(),376 Self::Tree(_) => {377 let mut buf = String::with_capacity(self.len());378 write_buf(self, &mut buf);379 buf.into()380 }381 }382 }383 pub fn len(&self) -> usize {384 match self {385 Self::Flat(v) => v.len(),386 Self::Tree(t) => t.2,387 }388 }389 pub fn is_empty(&self) -> bool {390 match self {391 Self::Flat(v) => v.is_empty(),392 // Can't create non-flat empty string393 Self::Tree(_) => false,394 }395 }396}397impl<T> From<T> for StrValue398where399 IStr: From<T>,400{401 fn from(value: T) -> Self {402 Self::Flat(IStr::from(value))403 }404}405impl Display for StrValue {406 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {407 match self {408 Self::Flat(v) => write!(f, "{v}"),409 Self::Tree(t) => {410 write!(f, "{}", t.0)?;411 write!(f, "{}", t.1)412 }413 }414 }415}416impl PartialEq for StrValue {417 // False positive, into_flat returns not StrValue, but IStr, thus no infinite recursion here.418 #[allow(clippy::unconditional_recursion)]419 fn eq(&self, other: &Self) -> bool {420 let a = self.clone().into_flat();421 let b = other.clone().into_flat();422 a == b423 }424}425impl Eq for StrValue {}426impl PartialOrd for StrValue {427 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {428 Some(self.cmp(other))429 }430}431impl Ord for StrValue {432 fn cmp(&self, other: &Self) -> Ordering {433 let a = self.clone().into_flat();434 let b = other.clone().into_flat();435 a.cmp(&b)436 }437}438439/// Represents any valid Jsonnet value.440#[derive(Debug, Clone, Trace, Default)]441pub enum Val {442 /// Represents a Jsonnet boolean.443 Bool(bool),444 /// Represents a Jsonnet null value.445 #[default]446 Null,447 /// Represents a Jsonnet string.448 Str(StrValue),449 /// Represents a Jsonnet number.450 /// Should be finite, and not NaN451 /// This restriction isn't enforced by enum, as enum field can't be marked as private452 Num(NumValue),453 /// Experimental bigint454 #[cfg(feature = "exp-bigint")]455 BigInt(#[trace(skip)] Box<num_bigint::BigInt>),456 /// Represents a Jsonnet array.457 Arr(ArrValue),458 /// Represents a Jsonnet object.459 Obj(ObjValue),460 /// Represents a Jsonnet function.461 Func(FuncVal),462}463464#[cfg(target_pointer_width = "64")]465static_assertions::assert_eq_size!(Val, [u8; 24]);466467impl From<IndexableVal> for Val {468 fn from(v: IndexableVal) -> Self {469 match v {470 IndexableVal::Str(s) => Self::string(s),471 IndexableVal::Arr(a) => Self::Arr(a),472 }473 }474}475476impl Val {477 pub const fn as_bool(&self) -> Option<bool> {478 match self {479 Self::Bool(v) => Some(*v),480 _ => None,481 }482 }483 pub const fn as_null(&self) -> Option<()> {484 match self {485 Self::Null => Some(()),486 _ => None,487 }488 }489 pub fn as_str(&self) -> Option<IStr> {490 match self {491 Self::Str(s) => Some(s.clone().into_flat()),492 _ => None,493 }494 }495 pub const fn as_num(&self) -> Option<f64> {496 match self {497 Self::Num(n) => Some(n.get()),498 _ => None,499 }500 }501 #[cfg(feature = "exp-bigint")]502 pub fn as_bigint(&self) -> Option<num_bigint::BigInt> {503 match self {504 Self::BigInt(n) => Some(*n.clone()),505 _ => None,506 }507 }508 pub fn as_arr(&self) -> Option<ArrValue> {509 match self {510 Self::Arr(a) => Some(a.clone()),511 _ => None,512 }513 }514 pub fn as_obj(&self) -> Option<ObjValue> {515 match self {516 Self::Obj(o) => Some(o.clone()),517 _ => None,518 }519 }520 pub fn as_func(&self) -> Option<FuncVal> {521 match self {522 Self::Func(f) => Some(f.clone()),523 _ => None,524 }525 }526527 pub const fn value_type(&self) -> ValType {528 match self {529 Self::Str(..) => ValType::Str,530 Self::Num(..) => ValType::Num,531 #[cfg(feature = "exp-bigint")]532 Self::BigInt(..) => ValType::BigInt,533 Self::Arr(..) => ValType::Arr,534 Self::Obj(..) => ValType::Obj,535 Self::Bool(_) => ValType::Bool,536 Self::Null => ValType::Null,537 Self::Func(..) => ValType::Func,538 }539 }540541 pub fn manifest(&self, format: impl ManifestFormat) -> Result<String> {542 fn manifest_dyn(val: &Val, manifest: &dyn ManifestFormat) -> Result<String> {543 manifest.manifest(val.clone())544 }545 manifest_dyn(self, &format)546 }547548 pub fn to_string(&self) -> Result<IStr> {549 Ok(match self {550 Self::Bool(true) => "true".into(),551 Self::Bool(false) => "false".into(),552 Self::Null => "null".into(),553 Self::Str(s) => s.clone().into_flat(),554 _ => self.manifest(ToStringFormat).map(IStr::from)?,555 })556 }557558 pub fn into_indexable(self) -> Result<IndexableVal> {559 Ok(match self {560 Self::Str(s) => IndexableVal::Str(s.into_flat()),561 Self::Arr(arr) => IndexableVal::Arr(arr),562 _ => bail!(ValueIsNotIndexable(self.value_type())),563 })564 }565566 pub fn function(function: impl Into<FuncVal>) -> Self {567 Self::Func(function.into())568 }569 pub fn string(string: impl Into<StrValue>) -> Self {570 Self::Str(string.into())571 }572 pub fn num(num: impl Into<NumValue>) -> Self {573 Self::Num(num.into())574 }575 pub fn try_num<V, E>(num: V) -> Result<Self, E>576 where577 NumValue: TryFrom<V, Error = E>,578 {579 Ok(Self::Num(num.try_into()?))580 }581 pub fn arr(a: impl ArrayLike) -> Self {582 Self::Arr(ArrValue::new(a))583 }584585 pub fn try_cmp(a: &Val, b: &Val) -> Result<Ordering> {586 evaluate_compare_op(a, b, BinaryOpType::Lt)587 }588 pub fn try_mod(a: &Val, b: &Val) -> Result<Val> {589 evaluate_mod_op(a, b)590 }591}592593impl From<IStr> for Val {594 fn from(value: IStr) -> Self {595 Self::string(value)596 }597}598impl From<String> for Val {599 fn from(value: String) -> Self {600 Self::string(value)601 }602}603impl From<&str> for Val {604 fn from(value: &str) -> Self {605 Self::string(value)606 }607}608impl From<ObjValue> for Val {609 fn from(value: ObjValue) -> Self {610 Self::Obj(value)611 }612}613614const fn is_function_like(val: &Val) -> bool {615 matches!(val, Val::Func(_))616}617618/// Native implementation of `std.primitiveEquals`619pub fn primitive_equals(val_a: &Val, val_b: &Val) -> Result<bool> {620 Ok(match (val_a, val_b) {621 (Val::Bool(a), Val::Bool(b)) => a == b,622 (Val::Null, Val::Null) => true,623 (Val::Str(a), Val::Str(b)) => a == b,624 (Val::Num(a), Val::Num(b)) => (a.get() - b.get()).abs() <= f64::EPSILON,625 #[cfg(feature = "exp-bigint")]626 (Val::BigInt(a), Val::BigInt(b)) => a == b,627 (Val::Arr(_), Val::Arr(_)) => {628 bail!("primitiveEquals operates on primitive types, got array")629 }630 (Val::Obj(_), Val::Obj(_)) => {631 bail!("primitiveEquals operates on primitive types, got object")632 }633 (a, b) if is_function_like(a) && is_function_like(b) => {634 bail!("cannot test equality of functions")635 }636 (_, _) => false,637 })638}639640/// Native implementation of `std.equals`641pub fn equals(val_a: &Val, val_b: &Val) -> Result<bool> {642 if val_a.value_type() != val_b.value_type() {643 return Ok(false);644 }645 match (val_a, val_b) {646 (Val::Arr(a), Val::Arr(b)) => {647 if ArrValue::ptr_eq(a, b) {648 return Ok(true);649 }650 if a.len() != b.len() {651 return Ok(false);652 }653 for (a, b) in a.iter().zip(b.iter()) {654 if !equals(&a?, &b?)? {655 return Ok(false);656 }657 }658 Ok(true)659 }660 (Val::Obj(a), Val::Obj(b)) => {661 if ObjValue::ptr_eq(a, b) {662 return Ok(true);663 }664 let fields = a.fields(665 #[cfg(feature = "exp-preserve-order")]666 false,667 );668 if fields669 != b.fields(670 #[cfg(feature = "exp-preserve-order")]671 false,672 ) {673 return Ok(false);674 }675 for field in fields {676 if !equals(677 &a.get(field.clone())?.expect("field exists"),678 &b.get(field)?.expect("field exists"),679 )? {680 return Ok(false);681 }682 }683 Ok(true)684 }685 (a, b) => Ok(primitive_equals(a, b)?),686 }687}crates/jrsonnet-ir-parser/src/lib.rsdiffbeforeafterboth--- a/crates/jrsonnet-ir-parser/src/lib.rs
+++ b/crates/jrsonnet-ir-parser/src/lib.rs
@@ -1,11 +1,11 @@
use jrsonnet_gcmodule::Acyclic;
use jrsonnet_ir::{
- unescape, ArgsDesc, AssertExpr, AssertStmt, BinaryOp, BinaryOpType, BindSpec, CompSpec,
- Destruct, Expr, ExprParam, ExprParams, FieldMember, FieldName, ForSpecData, IStr, IfElse,
- IfSpecData, ImportKind, IndexPart, LiteralType, Member, NumValue, ObjBody, ObjComp, ObjMembers,
- Slice, SliceDesc, Source, Span, Spanned, UnaryOpType, Visibility,
+ ArgsDesc, AssertExpr, AssertStmt, BinaryOp, BinaryOpType, BindSpec, CompSpec, Destruct, Expr,
+ ExprParam, ExprParams, FieldMember, FieldName, ForSpecData, IStr, IfElse, IfSpecData,
+ ImportKind, IndexPart, LiteralType, Member, NumValue, ObjBody, ObjComp, ObjMembers, Slice,
+ SliceDesc, Source, Span, Spanned, UnaryOpType, Visibility, unescape,
};
-use jrsonnet_lexer::{collect_lexed_str_block, Lexeme, Lexer, Span as LexSpan, SyntaxKind, T};
+use jrsonnet_lexer::{Lexeme, Lexer, Span as LexSpan, SyntaxKind, T, collect_lexed_str_block};
pub struct ParserSettings {
pub source: Source,
crates/jrsonnet-ir/src/expr.rsdiffbeforeafterboth--- a/crates/jrsonnet-ir/src/expr.rs
+++ b/crates/jrsonnet-ir/src/expr.rs
@@ -7,9 +7,9 @@
use jrsonnet_interner::IStr;
use crate::{
+ NumValue,
function::{FunctionSignature, ParamDefault, ParamName, ParamParse},
source::Source,
- NumValue,
};
#[derive(Debug, PartialEq, Acyclic)]
crates/jrsonnet-macros/src/lib.rsdiffbeforeafterboth--- a/crates/jrsonnet-macros/src/lib.rs
+++ b/crates/jrsonnet-macros/src/lib.rs
@@ -3,14 +3,13 @@
use proc_macro2::TokenStream;
use quote::{quote, quote_spanned};
use syn::{
- parenthesized,
+ Attribute, DeriveInput, Error, Expr, ExprClosure, FnArg, GenericArgument, Ident, ItemFn,
+ LitStr, Meta, Pat, Path, PathArguments, Result, ReturnType, Token, Type, parenthesized,
parse::{Parse, ParseStream},
parse_macro_input,
punctuated::Punctuated,
spanned::Spanned,
token::Comma,
- Attribute, DeriveInput, Error, Expr, ExprClosure, FnArg, GenericArgument, Ident, ItemFn,
- LitStr, Meta, Pat, Path, PathArguments, Result, ReturnType, Token, Type,
};
use self::typed::{derive_from_untyped_inner, derive_into_untyped_inner, derive_typed_inner};
crates/jrsonnet-stdlib/src/arrays.rsdiffbeforeafterboth--- a/crates/jrsonnet-stdlib/src/arrays.rs
+++ b/crates/jrsonnet-stdlib/src/arrays.rs
@@ -1,12 +1,11 @@
#![allow(non_snake_case)]
use jrsonnet_evaluator::{
- bail, error,
- function::{builtin, NativeFn},
+ Either, IStr, ObjValue, ObjValueBuilder, Result, ResultExt, Thunk, Val, bail, error,
+ function::{NativeFn, builtin},
runtime_error,
typed::{BoundedUsize, Either2, FromUntyped},
- val::{equals, ArrValue, IndexableVal},
- Either, IStr, ObjValue, ObjValueBuilder, Result, ResultExt, Thunk, Val,
+ val::{ArrValue, IndexableVal, equals},
};
pub fn eval_on_empty(on_empty: Option<Thunk<Val>>) -> Result<Val> {
crates/jrsonnet-stdlib/src/compat.rsdiffbeforeafterboth--- a/crates/jrsonnet-stdlib/src/compat.rs
+++ b/crates/jrsonnet-stdlib/src/compat.rs
@@ -1,6 +1,6 @@
use std::cmp::Ordering;
-use jrsonnet_evaluator::{function::builtin, val::ArrValue, Result, Val};
+use jrsonnet_evaluator::{Result, Val, function::builtin, val::ArrValue};
#[builtin]
#[allow(non_snake_case)]
crates/jrsonnet-stdlib/src/lib.rsdiffbeforeafterboth--- a/crates/jrsonnet-stdlib/src/lib.rs
+++ b/crates/jrsonnet-stdlib/src/lib.rs
@@ -12,7 +12,12 @@
pub use encoding::*;
pub use hash::*;
use jrsonnet_evaluator::{
- IStr, InitialContextBuilder, NumValue, ObjValue, ObjValueBuilder, Source, Thunk, Val, error::Result, function::{CallLocation, FuncVal, builtin_id}, tla::TlaArg, trace::PathResolver, typed::SerializeTypedObj as _
+ IStr, InitialContextBuilder, NumValue, ObjValue, ObjValueBuilder, Source, Thunk, Val,
+ error::Result,
+ function::{CallLocation, FuncVal, builtin_id},
+ tla::TlaArg,
+ trace::PathResolver,
+ typed::SerializeTypedObj as _,
};
use jrsonnet_gcmodule::{Acyclic, Cc, Trace};
use jrsonnet_macros::{IntoUntyped, Typed};
crates/jrsonnet-stdlib/src/manifest/toml.rsdiffbeforeafterboth--- a/crates/jrsonnet-stdlib/src/manifest/toml.rs
+++ b/crates/jrsonnet-stdlib/src/manifest/toml.rs
@@ -1,7 +1,10 @@
use std::borrow::Cow;
use jrsonnet_evaluator::{
- Error, IStr, ObjValue, Result, ResultExt, Val, bail, ensure_sufficient_stack, in_description_frame, manifest::{ManifestFormat, escape_string_json_buf}, val::ArrValue
+ Error, IStr, ObjValue, Result, ResultExt, Val, bail, ensure_sufficient_stack,
+ in_description_frame,
+ manifest::{ManifestFormat, escape_string_json_buf},
+ val::ArrValue,
};
pub struct TomlFormat<'s> {
@@ -218,14 +221,16 @@
}
first = false;
path.push(k.clone());
- ensure_sufficient_stack(|| in_description_frame(
- || format!("section <{k}> manifestification"),
- || match v {
- Val::Obj(obj) => manifest_table(&obj, path, buf, cur_padding, options),
- Val::Arr(arr) => manifest_table_array(&arr, path, buf, cur_padding, options),
- _ => unreachable!("iterating over sections"),
- },
- ))?;
+ ensure_sufficient_stack(|| {
+ in_description_frame(
+ || format!("section <{k}> manifestification"),
+ || match v {
+ Val::Obj(obj) => manifest_table(&obj, path, buf, cur_padding, options),
+ Val::Arr(arr) => manifest_table_array(&arr, path, buf, cur_padding, options),
+ _ => unreachable!("iterating over sections"),
+ },
+ )
+ })?;
path.pop();
}
Ok(())
crates/jrsonnet-stdlib/src/misc.rsdiffbeforeafterboth--- a/crates/jrsonnet-stdlib/src/misc.rs
+++ b/crates/jrsonnet-stdlib/src/misc.rs
@@ -1,13 +1,12 @@
use std::{cell::RefCell, collections::BTreeSet};
use jrsonnet_evaluator::{
- bail,
+ Either, IStr, ObjValue, ObjValueBuilder, ResultExt, Thunk, Val, bail,
error::{ErrorKind::*, Result},
- function::{builtin, CallLocation, FuncVal},
+ function::{CallLocation, FuncVal, builtin},
manifest::JsonFormat,
typed::{Either2, Either4},
- val::{equals, ArrValue},
- Either, IStr, ObjValue, ObjValueBuilder, ResultExt, Thunk, Val,
+ val::{ArrValue, equals},
};
use jrsonnet_gcmodule::Cc;
crates/jrsonnet-stdlib/src/operator.rsdiffbeforeafterboth--- a/crates/jrsonnet-stdlib/src/operator.rs
+++ b/crates/jrsonnet-stdlib/src/operator.rs
@@ -2,11 +2,11 @@
//! However, in our case we instead implement them in native, and implement native functions on top of core for backwards compatibility
use jrsonnet_evaluator::{
+ IStr, NumValue, Result, Val,
function::builtin,
stdlib::std_format,
typed::{Either, Either2},
val::{equals, primitive_equals},
- IStr, NumValue, Result, Val,
};
#[builtin]
crates/jrsonnet-stdlib/src/sets.rsdiffbeforeafterboth--- a/crates/jrsonnet-stdlib/src/sets.rs
+++ b/crates/jrsonnet-stdlib/src/sets.rs
@@ -1,6 +1,6 @@
use std::cmp::Ordering;
-use jrsonnet_evaluator::{function::builtin, val::ArrValue, Result, Thunk, Val};
+use jrsonnet_evaluator::{Result, Thunk, Val, function::builtin, val::ArrValue};
use crate::keyf::KeyF;
crates/jrsonnet-stdlib/src/sort.rsdiffbeforeafterboth--- a/crates/jrsonnet-stdlib/src/sort.rs
+++ b/crates/jrsonnet-stdlib/src/sort.rs
@@ -3,10 +3,9 @@
use std::cmp::Ordering;
use jrsonnet_evaluator::{
- bail,
+ Result, Thunk, Val, bail,
function::builtin,
- val::{equals, ArrValue},
- Result, Thunk, Val,
+ val::{ArrValue, equals},
};
use crate::{eval_on_empty, keyf::KeyF};
tests/tests/builtin.rsdiffbeforeafterboth--- a/tests/tests/builtin.rs
+++ b/tests/tests/builtin.rs
@@ -1,7 +1,11 @@
mod common;
use jrsonnet_evaluator::{
- ContextInitializer, FileImportResolver, InitialContextBuilder, Result, Source, State, Thunk, Val, function::{CallLocation, FuncVal, builtin, builtin::{Builtin}}, trace::PathResolver, typed::FromUntyped
+ ContextInitializer, FileImportResolver, InitialContextBuilder, Result, Source, State, Thunk,
+ Val,
+ function::{CallLocation, FuncVal, builtin, builtin::Builtin},
+ trace::PathResolver,
+ typed::FromUntyped,
};
use jrsonnet_gcmodule::Trace;
use jrsonnet_stdlib::ContextInitializer as StdContextInitializer;
tests/tests/common.rsdiffbeforeafterboth--- a/tests/tests/common.rs
+++ b/tests/tests/common.rs
@@ -1,5 +1,7 @@
use jrsonnet_evaluator::{
- ContextBuilder, ContextInitializer as ContextInitializerT, InitialContextBuilder, ObjValueBuilder, Result, Thunk, Val, bail, function::{FuncVal, builtin}, Source
+ ContextBuilder, ContextInitializer as ContextInitializerT, InitialContextBuilder,
+ ObjValueBuilder, Result, Source, Thunk, Val, bail,
+ function::{FuncVal, builtin},
};
use jrsonnet_gcmodule::Trace;