git.delta.rocks / jrsonnet / refs/commits / 4e0dbf427e61

difftreelog

style update rustfmt

Yaroslav Bolyukin2023-07-26parent: #f883d5e.patch.diff
in: master

9 files changed

modifiedcmds/jrsonnet/src/main.rsdiffbeforeafterboth
--- a/cmds/jrsonnet/src/main.rs
+++ b/cmds/jrsonnet/src/main.rs
@@ -208,7 +208,10 @@
 			create_dir_all(dir)?;
 		}
 		let Val::Obj(obj) = val else {
-			throw!("value should be object for --multi manifest, got {}", val.value_type())
+			throw!(
+				"value should be object for --multi manifest, got {}",
+				val.value_type()
+			)
 		};
 		for (field, data) in obj.iter(
 			#[cfg(feature = "exp-preserve-order")]
modifiedcrates/jrsonnet-evaluator/src/arr/spec.rsdiffbeforeafterboth
before · crates/jrsonnet-evaluator/src/arr/spec.rs
1use std::{cell::RefCell, iter, mem::replace, rc::Rc};23use jrsonnet_gcmodule::{Cc, Trace};4use jrsonnet_interner::{IBytes, IStr};5use jrsonnet_parser::LocExpr;67use super::ArrValue;8use crate::{9	error::ErrorKind::InfiniteRecursionDetected,10	evaluate,11	function::FuncVal,12	val::{StrValue, ThunkValue},13	Context, Error, Result, Thunk, Val,14};1516pub trait ArrayLike: Sized + Into<ArrValue> {17	fn len(&self) -> usize;18	fn is_empty(&self) -> bool {19		self.len() == 020	}21	fn get(&self, index: usize) -> Result<Option<Val>>;22	fn get_lazy(&self, index: usize) -> Option<Thunk<Val>>;23	fn get_cheap(&self, index: usize) -> Option<Val>;2425	fn reverse(self) -> ArrValue {26		ArrValue::Reverse(Cc::new(ReverseArray(self.into())))27	}28}2930#[derive(Debug, Clone, Trace)]31pub struct SliceArray {32	pub(crate) inner: ArrValue,33	pub(crate) from: u32,34	pub(crate) to: u32,35	pub(crate) step: u32,36}3738impl SliceArray {39	fn iter(&self) -> impl Iterator<Item = Result<Val>> + '_ {40		self.inner41			.iter()42			.skip(self.from as usize)43			.take((self.to - self.from) as usize)44			.step_by(self.step as usize)45	}4647	fn iter_lazy(&self) -> impl Iterator<Item = Thunk<Val>> + '_ {48		self.inner49			.iter_lazy()50			.skip(self.from as usize)51			.take((self.to - self.from) as usize)52			.step_by(self.step as usize)53	}5455	fn iter_cheap(&self) -> Option<impl crate::arr::ArrayLikeIter<Val> + '_> {56		Some(57			self.inner58				.iter_cheap()?59				.skip(self.from as usize)60				.take((self.to - self.from) as usize)61				.step_by(self.step as usize),62		)63	}64}65impl ArrayLike for SliceArray {66	fn len(&self) -> usize {67		iter::repeat(())68			.take((self.to - self.from) as usize)69			.step_by(self.step as usize)70			.count()71	}7273	fn get(&self, index: usize) -> Result<Option<Val>> {74		self.iter().nth(index).transpose()75	}7677	fn get_lazy(&self, index: usize) -> Option<Thunk<Val>> {78		self.iter_lazy().nth(index)79	}8081	fn get_cheap(&self, index: usize) -> Option<Val> {82		self.iter_cheap()?.nth(index)83	}84}85impl From<SliceArray> for ArrValue {86	fn from(value: SliceArray) -> Self {87		Self::Slice(Cc::new(value))88	}89}9091#[derive(Trace, Debug, Clone)]92pub struct CharArray(pub Rc<Vec<char>>);93impl ArrayLike for CharArray {94	fn len(&self) -> usize {95		self.0.len()96	}9798	fn get(&self, index: usize) -> Result<Option<Val>> {99		Ok(self.get_cheap(index))100	}101102	fn get_lazy(&self, index: usize) -> Option<Thunk<Val>> {103		self.get_cheap(index).map(Thunk::evaluated)104	}105106	fn get_cheap(&self, index: usize) -> Option<Val> {107		self.0108			.get(index)109			.map(|v| Val::Str(StrValue::Flat(IStr::from(*v))))110	}111}112impl From<CharArray> for ArrValue {113	fn from(value: CharArray) -> Self {114		ArrValue::Chars(value)115	}116}117118#[derive(Trace, Debug, Clone)]119pub struct BytesArray(pub IBytes);120impl ArrayLike for BytesArray {121	fn len(&self) -> usize {122		self.0.len()123	}124125	fn get(&self, index: usize) -> Result<Option<Val>> {126		Ok(self.get_cheap(index))127	}128129	fn get_lazy(&self, index: usize) -> Option<Thunk<Val>> {130		self.get_cheap(index).map(Thunk::evaluated)131	}132133	fn get_cheap(&self, index: usize) -> Option<Val> {134		self.0.get(index).map(|v| Val::Num(f64::from(*v)))135	}136}137impl From<BytesArray> for ArrValue {138	fn from(value: BytesArray) -> Self {139		ArrValue::Bytes(value)140	}141}142143#[derive(Debug, Trace, Clone)]144enum ArrayThunk<T: 'static + Trace> {145	Computed(Val),146	Errored(Error),147	Waiting(T),148	Pending,149}150151#[derive(Debug, Trace)]152pub struct ExprArrayInner {153	ctx: Context,154	cached: RefCell<Vec<ArrayThunk<LocExpr>>>,155}156#[derive(Debug, Trace, Clone)]157pub struct ExprArray(pub Cc<ExprArrayInner>);158impl ExprArray {159	pub fn new(ctx: Context, items: impl IntoIterator<Item = LocExpr>) -> Self {160		Self(Cc::new(ExprArrayInner {161			ctx,162			cached: RefCell::new(items.into_iter().map(ArrayThunk::Waiting).collect()),163		}))164	}165}166impl ArrayLike for ExprArray {167	fn len(&self) -> usize {168		self.0.cached.borrow().len()169	}170	fn get(&self, index: usize) -> Result<Option<Val>> {171		if index >= self.len() {172			return Ok(None);173		}174		match &self.0.cached.borrow()[index] {175			ArrayThunk::Computed(c) => return Ok(Some(c.clone())),176			ArrayThunk::Errored(e) => return Err(e.clone()),177			ArrayThunk::Pending => return Err(InfiniteRecursionDetected.into()),178			ArrayThunk::Waiting(..) => {}179		};180181		let ArrayThunk::Waiting(expr) = replace(&mut self.0.cached.borrow_mut()[index], ArrayThunk::Pending) else {182			unreachable!()183		};184185		let new_value = match evaluate(self.0.ctx.clone(), &expr) {186			Ok(v) => v,187			Err(e) => {188				self.0.cached.borrow_mut()[index] = ArrayThunk::Errored(e.clone());189				return Err(e);190			}191		};192		self.0.cached.borrow_mut()[index] = ArrayThunk::Computed(new_value.clone());193		Ok(Some(new_value))194	}195	fn get_lazy(&self, index: usize) -> Option<Thunk<Val>> {196		#[derive(Trace)]197		struct ArrayElement {198			arr_thunk: ExprArray,199			index: usize,200		}201202		impl ThunkValue for ArrayElement {203			type Output = Val;204205			fn get(self: Box<Self>) -> Result<Self::Output> {206				self.arr_thunk207					.get(self.index)208					.transpose()209					.expect("index checked")210			}211		}212213		if index >= self.len() {214			return None;215		}216		match &self.0.cached.borrow()[index] {217			ArrayThunk::Computed(c) => return Some(Thunk::evaluated(c.clone())),218			ArrayThunk::Errored(e) => return Some(Thunk::errored(e.clone())),219			ArrayThunk::Waiting(_) | ArrayThunk::Pending => {}220		};221222		Some(Thunk::new(ArrayElement {223			arr_thunk: self.clone(),224			index,225		}))226	}227	fn get_cheap(&self, _index: usize) -> Option<Val> {228		None229	}230}231impl From<ExprArray> for ArrValue {232	fn from(value: ExprArray) -> Self {233		Self::Expr(value)234	}235}236237#[derive(Trace, Debug, Clone)]238pub struct ExtendedArray {239	pub a: ArrValue,240	pub b: ArrValue,241	split: usize,242	len: usize,243}244impl ExtendedArray {245	pub fn new(a: ArrValue, b: ArrValue) -> Self {246		let a_len = a.len();247		let b_len = b.len();248		Self {249			a,250			b,251			split: a_len,252			len: a_len.checked_add(b_len).expect("too large array value"),253		}254	}255}256257struct WithExactSize<I>(I, usize);258impl<I, T> Iterator for WithExactSize<I>259where260	I: Iterator<Item = T>,261{262	type Item = T;263264	fn next(&mut self) -> Option<Self::Item> {265		self.0.next()266	}267	fn nth(&mut self, n: usize) -> Option<Self::Item> {268		self.0.nth(n)269	}270	fn size_hint(&self) -> (usize, Option<usize>) {271		(self.1, Some(self.1))272	}273}274impl<I> DoubleEndedIterator for WithExactSize<I>275where276	I: DoubleEndedIterator,277{278	fn next_back(&mut self) -> Option<Self::Item> {279		self.0.next_back()280	}281	fn nth_back(&mut self, n: usize) -> Option<Self::Item> {282		self.0.nth_back(n)283	}284}285impl<I> ExactSizeIterator for WithExactSize<I>286where287	I: Iterator,288{289	fn len(&self) -> usize {290		self.1291	}292}293impl ArrayLike for ExtendedArray {294	fn get(&self, index: usize) -> Result<Option<Val>> {295		if self.split > index {296			self.a.get(index)297		} else {298			self.b.get(index - self.split)299		}300	}301	fn get_lazy(&self, index: usize) -> Option<Thunk<Val>> {302		if self.split > index {303			self.a.get_lazy(index)304		} else {305			self.b.get_lazy(index - self.split)306		}307	}308309	fn len(&self) -> usize {310		self.len311	}312313	fn get_cheap(&self, index: usize) -> Option<Val> {314		if self.split > index {315			self.a.get_cheap(index)316		} else {317			self.b.get_cheap(index - self.split)318		}319	}320}321impl From<ExtendedArray> for ArrValue {322	fn from(value: ExtendedArray) -> Self {323		Self::Extended(Cc::new(value))324	}325}326327#[derive(Trace, Debug, Clone)]328pub struct LazyArray(pub Cc<Vec<Thunk<Val>>>);329impl ArrayLike for LazyArray {330	fn len(&self) -> usize {331		self.0.len()332	}333	fn get(&self, index: usize) -> Result<Option<Val>> {334		let Some(v) = self.0.get(index) else {335			return Ok(None);336		};337		v.evaluate().map(Some)338	}339	fn get_cheap(&self, _index: usize) -> Option<Val> {340		None341	}342	fn get_lazy(&self, index: usize) -> Option<Thunk<Val>> {343		self.0.get(index).cloned()344	}345}346impl From<LazyArray> for ArrValue {347	fn from(value: LazyArray) -> Self {348		Self::Lazy(value)349	}350}351352#[derive(Trace, Debug, Clone)]353pub struct EagerArray(pub Cc<Vec<Val>>);354impl ArrayLike for EagerArray {355	fn len(&self) -> usize {356		self.0.len()357	}358359	fn get(&self, index: usize) -> Result<Option<Val>> {360		Ok(self.0.get(index).cloned())361	}362363	fn get_lazy(&self, index: usize) -> Option<Thunk<Val>> {364		self.0.get(index).cloned().map(Thunk::evaluated)365	}366367	fn get_cheap(&self, index: usize) -> Option<Val> {368		self.0.get(index).cloned()369	}370}371impl From<EagerArray> for ArrValue {372	fn from(value: EagerArray) -> Self {373		Self::Eager(value)374	}375}376377/// Inclusive range type378#[derive(Debug, Trace, Clone, PartialEq, Eq)]379pub struct RangeArray {380	start: i32,381	end: i32,382}383impl RangeArray {384	pub fn empty() -> Self {385		Self::new_exclusive(0, 0)386	}387	pub fn new_exclusive(start: i32, end: i32) -> Self {388		end.checked_sub(1)389			.map_or_else(Self::empty, |end| Self { start, end })390	}391	pub fn new_inclusive(start: i32, end: i32) -> Self {392		Self { start, end }393	}394	fn range(&self) -> impl Iterator<Item = i32> + ExactSizeIterator + DoubleEndedIterator {395		WithExactSize(396			self.start..=self.end,397			(self.end as usize)398				.wrapping_sub(self.start as usize)399				.wrapping_add(1),400		)401	}402}403404impl ArrayLike for RangeArray {405	fn len(&self) -> usize {406		self.range().len()407	}408	fn is_empty(&self) -> bool {409		self.range().len() == 0410	}411412	fn get(&self, index: usize) -> Result<Option<Val>> {413		Ok(self.get_cheap(index))414	}415416	fn get_lazy(&self, index: usize) -> Option<Thunk<Val>> {417		self.get_cheap(index).map(Thunk::evaluated)418	}419420	fn get_cheap(&self, index: usize) -> Option<Val> {421		self.range().nth(index).map(|i| Val::Num(f64::from(i)))422	}423}424impl From<RangeArray> for ArrValue {425	fn from(value: RangeArray) -> Self {426		Self::Range(value)427	}428}429430#[derive(Debug, Trace, Clone)]431pub struct ReverseArray(pub ArrValue);432impl ArrayLike for ReverseArray {433	fn len(&self) -> usize {434		self.0.len()435	}436437	fn get(&self, index: usize) -> Result<Option<Val>> {438		self.0.get(self.0.len() - index - 1)439	}440441	fn get_lazy(&self, index: usize) -> Option<Thunk<Val>> {442		self.0.get_lazy(self.0.len() - index - 1)443	}444445	fn get_cheap(&self, index: usize) -> Option<Val> {446		self.0.get_cheap(self.0.len() - index - 1)447	}448	fn reverse(self) -> ArrValue {449		self.0450	}451}452impl From<ReverseArray> for ArrValue {453	fn from(value: ReverseArray) -> Self {454		Self::Reverse(Cc::new(value))455	}456}457458#[derive(Trace, Debug)]459pub struct MappedArrayInner {460	inner: ArrValue,461	cached: RefCell<Vec<ArrayThunk<()>>>,462	mapper: FuncVal,463}464#[derive(Trace, Debug, Clone)]465pub struct MappedArray(Cc<MappedArrayInner>);466impl MappedArray {467	pub fn new(inner: ArrValue, mapper: FuncVal) -> Self {468		let len = inner.len();469		Self(Cc::new(MappedArrayInner {470			inner,471			cached: RefCell::new(vec![ArrayThunk::Waiting(()); len]),472			mapper,473		}))474	}475}476impl ArrayLike for MappedArray {477	fn len(&self) -> usize {478		self.0.cached.borrow().len()479	}480481	fn get(&self, index: usize) -> Result<Option<Val>> {482		if index >= self.len() {483			return Ok(None);484		}485		match &self.0.cached.borrow()[index] {486			ArrayThunk::Computed(c) => return Ok(Some(c.clone())),487			ArrayThunk::Errored(e) => return Err(e.clone()),488			ArrayThunk::Pending => return Err(InfiniteRecursionDetected.into()),489			ArrayThunk::Waiting(..) => {}490		};491492		let ArrayThunk::Waiting(_) = replace(&mut self.0.cached.borrow_mut()[index], ArrayThunk::Pending) else {493			unreachable!()494		};495496		let val = self497			.0498			.inner499			.get(index)500			.transpose()501			.expect("index checked")502			.and_then(|r| self.0.mapper.evaluate_simple(&(r,), false));503504		let new_value = match val {505			Ok(v) => v,506			Err(e) => {507				self.0.cached.borrow_mut()[index] = ArrayThunk::Errored(e.clone());508				return Err(e);509			}510		};511		self.0.cached.borrow_mut()[index] = ArrayThunk::Computed(new_value.clone());512		Ok(Some(new_value))513	}514	fn get_lazy(&self, index: usize) -> Option<Thunk<Val>> {515		#[derive(Trace)]516		struct ArrayElement {517			arr_thunk: MappedArray,518			index: usize,519		}520521		impl ThunkValue for ArrayElement {522			type Output = Val;523524			fn get(self: Box<Self>) -> Result<Self::Output> {525				self.arr_thunk526					.get(self.index)527					.transpose()528					.expect("index checked")529			}530		}531532		if index >= self.len() {533			return None;534		}535		match &self.0.cached.borrow()[index] {536			ArrayThunk::Computed(c) => return Some(Thunk::evaluated(c.clone())),537			ArrayThunk::Errored(e) => return Some(Thunk::errored(e.clone())),538			ArrayThunk::Waiting(_) | ArrayThunk::Pending => {}539		};540541		Some(Thunk::new(ArrayElement {542			arr_thunk: self.clone(),543			index,544		}))545	}546547	fn get_cheap(&self, _index: usize) -> Option<Val> {548		None549	}550}551impl From<MappedArray> for ArrValue {552	fn from(value: MappedArray) -> Self {553		Self::Mapped(value)554	}555}556557#[derive(Trace, Debug)]558pub struct RepeatedArrayInner {559	data: ArrValue,560	repeats: usize,561	total_len: usize,562}563#[derive(Trace, Debug, Clone)]564pub struct RepeatedArray(Cc<RepeatedArrayInner>);565impl RepeatedArray {566	pub fn new(data: ArrValue, repeats: usize) -> Option<Self> {567		let total_len = data.len().checked_mul(repeats)?;568		Some(Self(Cc::new(RepeatedArrayInner {569			data,570			repeats,571			total_len,572		})))573	}574	pub fn is_cheap(&self) -> bool {575		self.0.data.is_cheap()576	}577}578579impl ArrayLike for RepeatedArray {580	fn len(&self) -> usize {581		self.0.total_len582	}583584	fn get(&self, index: usize) -> Result<Option<Val>> {585		if index > self.0.total_len {586			return Ok(None);587		}588		self.0.data.get(index % self.0.data.len())589	}590591	fn get_lazy(&self, index: usize) -> Option<Thunk<Val>> {592		if index > self.0.total_len {593			return None;594		}595		self.0.data.get_lazy(index % self.0.data.len())596	}597598	fn get_cheap(&self, index: usize) -> Option<Val> {599		if index > self.0.total_len {600			return None;601		}602		self.0.data.get_cheap(index % self.0.data.len())603	}604}605impl From<RepeatedArray> for ArrValue {606	fn from(value: RepeatedArray) -> Self {607		Self::Repeated(value)608	}609}610611macro_rules! pass {612	($t:ident.$m:ident($($ident:ident),*)) => {613		match $t {614			Self::Bytes(e) => e.$m($($ident)*),615			Self::Chars(e) => e.$m($($ident)*),616			Self::Expr(e) => e.$m($($ident)*),617			Self::Lazy(e) => e.$m($($ident)*),618			Self::Eager(e) => e.$m($($ident)*),619			Self::Range(e) => e.$m($($ident)*),620			Self::Slice(e) => e.$m($($ident)*),621			Self::Extended(e) => e.$m($($ident)*),622			Self::Reverse(e) => e.$m($($ident)*),623			Self::Mapped(e) => e.$m($($ident)*),624			Self::Repeated(e) => e.$m($($ident)*),625		}626	};627}628pub(super) use pass;
after · crates/jrsonnet-evaluator/src/arr/spec.rs
1use std::{cell::RefCell, iter, mem::replace, rc::Rc};23use jrsonnet_gcmodule::{Cc, Trace};4use jrsonnet_interner::{IBytes, IStr};5use jrsonnet_parser::LocExpr;67use super::ArrValue;8use crate::{9	error::ErrorKind::InfiniteRecursionDetected,10	evaluate,11	function::FuncVal,12	val::{StrValue, ThunkValue},13	Context, Error, Result, Thunk, Val,14};1516pub trait ArrayLike: Sized + Into<ArrValue> {17	fn len(&self) -> usize;18	fn is_empty(&self) -> bool {19		self.len() == 020	}21	fn get(&self, index: usize) -> Result<Option<Val>>;22	fn get_lazy(&self, index: usize) -> Option<Thunk<Val>>;23	fn get_cheap(&self, index: usize) -> Option<Val>;2425	fn reverse(self) -> ArrValue {26		ArrValue::Reverse(Cc::new(ReverseArray(self.into())))27	}28}2930#[derive(Debug, Clone, Trace)]31pub struct SliceArray {32	pub(crate) inner: ArrValue,33	pub(crate) from: u32,34	pub(crate) to: u32,35	pub(crate) step: u32,36}3738impl SliceArray {39	fn iter(&self) -> impl Iterator<Item = Result<Val>> + '_ {40		self.inner41			.iter()42			.skip(self.from as usize)43			.take((self.to - self.from) as usize)44			.step_by(self.step as usize)45	}4647	fn iter_lazy(&self) -> impl Iterator<Item = Thunk<Val>> + '_ {48		self.inner49			.iter_lazy()50			.skip(self.from as usize)51			.take((self.to - self.from) as usize)52			.step_by(self.step as usize)53	}5455	fn iter_cheap(&self) -> Option<impl crate::arr::ArrayLikeIter<Val> + '_> {56		Some(57			self.inner58				.iter_cheap()?59				.skip(self.from as usize)60				.take((self.to - self.from) as usize)61				.step_by(self.step as usize),62		)63	}64}65impl ArrayLike for SliceArray {66	fn len(&self) -> usize {67		iter::repeat(())68			.take((self.to - self.from) as usize)69			.step_by(self.step as usize)70			.count()71	}7273	fn get(&self, index: usize) -> Result<Option<Val>> {74		self.iter().nth(index).transpose()75	}7677	fn get_lazy(&self, index: usize) -> Option<Thunk<Val>> {78		self.iter_lazy().nth(index)79	}8081	fn get_cheap(&self, index: usize) -> Option<Val> {82		self.iter_cheap()?.nth(index)83	}84}85impl From<SliceArray> for ArrValue {86	fn from(value: SliceArray) -> Self {87		Self::Slice(Cc::new(value))88	}89}9091#[derive(Trace, Debug, Clone)]92pub struct CharArray(pub Rc<Vec<char>>);93impl ArrayLike for CharArray {94	fn len(&self) -> usize {95		self.0.len()96	}9798	fn get(&self, index: usize) -> Result<Option<Val>> {99		Ok(self.get_cheap(index))100	}101102	fn get_lazy(&self, index: usize) -> Option<Thunk<Val>> {103		self.get_cheap(index).map(Thunk::evaluated)104	}105106	fn get_cheap(&self, index: usize) -> Option<Val> {107		self.0108			.get(index)109			.map(|v| Val::Str(StrValue::Flat(IStr::from(*v))))110	}111}112impl From<CharArray> for ArrValue {113	fn from(value: CharArray) -> Self {114		ArrValue::Chars(value)115	}116}117118#[derive(Trace, Debug, Clone)]119pub struct BytesArray(pub IBytes);120impl ArrayLike for BytesArray {121	fn len(&self) -> usize {122		self.0.len()123	}124125	fn get(&self, index: usize) -> Result<Option<Val>> {126		Ok(self.get_cheap(index))127	}128129	fn get_lazy(&self, index: usize) -> Option<Thunk<Val>> {130		self.get_cheap(index).map(Thunk::evaluated)131	}132133	fn get_cheap(&self, index: usize) -> Option<Val> {134		self.0.get(index).map(|v| Val::Num(f64::from(*v)))135	}136}137impl From<BytesArray> for ArrValue {138	fn from(value: BytesArray) -> Self {139		ArrValue::Bytes(value)140	}141}142143#[derive(Debug, Trace, Clone)]144enum ArrayThunk<T: 'static + Trace> {145	Computed(Val),146	Errored(Error),147	Waiting(T),148	Pending,149}150151#[derive(Debug, Trace)]152pub struct ExprArrayInner {153	ctx: Context,154	cached: RefCell<Vec<ArrayThunk<LocExpr>>>,155}156#[derive(Debug, Trace, Clone)]157pub struct ExprArray(pub Cc<ExprArrayInner>);158impl ExprArray {159	pub fn new(ctx: Context, items: impl IntoIterator<Item = LocExpr>) -> Self {160		Self(Cc::new(ExprArrayInner {161			ctx,162			cached: RefCell::new(items.into_iter().map(ArrayThunk::Waiting).collect()),163		}))164	}165}166impl ArrayLike for ExprArray {167	fn len(&self) -> usize {168		self.0.cached.borrow().len()169	}170	fn get(&self, index: usize) -> Result<Option<Val>> {171		if index >= self.len() {172			return Ok(None);173		}174		match &self.0.cached.borrow()[index] {175			ArrayThunk::Computed(c) => return Ok(Some(c.clone())),176			ArrayThunk::Errored(e) => return Err(e.clone()),177			ArrayThunk::Pending => return Err(InfiniteRecursionDetected.into()),178			ArrayThunk::Waiting(..) => {}179		};180181		let ArrayThunk::Waiting(expr) =182			replace(&mut self.0.cached.borrow_mut()[index], ArrayThunk::Pending)183		else {184			unreachable!()185		};186187		let new_value = match evaluate(self.0.ctx.clone(), &expr) {188			Ok(v) => v,189			Err(e) => {190				self.0.cached.borrow_mut()[index] = ArrayThunk::Errored(e.clone());191				return Err(e);192			}193		};194		self.0.cached.borrow_mut()[index] = ArrayThunk::Computed(new_value.clone());195		Ok(Some(new_value))196	}197	fn get_lazy(&self, index: usize) -> Option<Thunk<Val>> {198		#[derive(Trace)]199		struct ArrayElement {200			arr_thunk: ExprArray,201			index: usize,202		}203204		impl ThunkValue for ArrayElement {205			type Output = Val;206207			fn get(self: Box<Self>) -> Result<Self::Output> {208				self.arr_thunk209					.get(self.index)210					.transpose()211					.expect("index checked")212			}213		}214215		if index >= self.len() {216			return None;217		}218		match &self.0.cached.borrow()[index] {219			ArrayThunk::Computed(c) => return Some(Thunk::evaluated(c.clone())),220			ArrayThunk::Errored(e) => return Some(Thunk::errored(e.clone())),221			ArrayThunk::Waiting(_) | ArrayThunk::Pending => {}222		};223224		Some(Thunk::new(ArrayElement {225			arr_thunk: self.clone(),226			index,227		}))228	}229	fn get_cheap(&self, _index: usize) -> Option<Val> {230		None231	}232}233impl From<ExprArray> for ArrValue {234	fn from(value: ExprArray) -> Self {235		Self::Expr(value)236	}237}238239#[derive(Trace, Debug, Clone)]240pub struct ExtendedArray {241	pub a: ArrValue,242	pub b: ArrValue,243	split: usize,244	len: usize,245}246impl ExtendedArray {247	pub fn new(a: ArrValue, b: ArrValue) -> Self {248		let a_len = a.len();249		let b_len = b.len();250		Self {251			a,252			b,253			split: a_len,254			len: a_len.checked_add(b_len).expect("too large array value"),255		}256	}257}258259struct WithExactSize<I>(I, usize);260impl<I, T> Iterator for WithExactSize<I>261where262	I: Iterator<Item = T>,263{264	type Item = T;265266	fn next(&mut self) -> Option<Self::Item> {267		self.0.next()268	}269	fn nth(&mut self, n: usize) -> Option<Self::Item> {270		self.0.nth(n)271	}272	fn size_hint(&self) -> (usize, Option<usize>) {273		(self.1, Some(self.1))274	}275}276impl<I> DoubleEndedIterator for WithExactSize<I>277where278	I: DoubleEndedIterator,279{280	fn next_back(&mut self) -> Option<Self::Item> {281		self.0.next_back()282	}283	fn nth_back(&mut self, n: usize) -> Option<Self::Item> {284		self.0.nth_back(n)285	}286}287impl<I> ExactSizeIterator for WithExactSize<I>288where289	I: Iterator,290{291	fn len(&self) -> usize {292		self.1293	}294}295impl ArrayLike for ExtendedArray {296	fn get(&self, index: usize) -> Result<Option<Val>> {297		if self.split > index {298			self.a.get(index)299		} else {300			self.b.get(index - self.split)301		}302	}303	fn get_lazy(&self, index: usize) -> Option<Thunk<Val>> {304		if self.split > index {305			self.a.get_lazy(index)306		} else {307			self.b.get_lazy(index - self.split)308		}309	}310311	fn len(&self) -> usize {312		self.len313	}314315	fn get_cheap(&self, index: usize) -> Option<Val> {316		if self.split > index {317			self.a.get_cheap(index)318		} else {319			self.b.get_cheap(index - self.split)320		}321	}322}323impl From<ExtendedArray> for ArrValue {324	fn from(value: ExtendedArray) -> Self {325		Self::Extended(Cc::new(value))326	}327}328329#[derive(Trace, Debug, Clone)]330pub struct LazyArray(pub Cc<Vec<Thunk<Val>>>);331impl ArrayLike for LazyArray {332	fn len(&self) -> usize {333		self.0.len()334	}335	fn get(&self, index: usize) -> Result<Option<Val>> {336		let Some(v) = self.0.get(index) else {337			return Ok(None);338		};339		v.evaluate().map(Some)340	}341	fn get_cheap(&self, _index: usize) -> Option<Val> {342		None343	}344	fn get_lazy(&self, index: usize) -> Option<Thunk<Val>> {345		self.0.get(index).cloned()346	}347}348impl From<LazyArray> for ArrValue {349	fn from(value: LazyArray) -> Self {350		Self::Lazy(value)351	}352}353354#[derive(Trace, Debug, Clone)]355pub struct EagerArray(pub Cc<Vec<Val>>);356impl ArrayLike for EagerArray {357	fn len(&self) -> usize {358		self.0.len()359	}360361	fn get(&self, index: usize) -> Result<Option<Val>> {362		Ok(self.0.get(index).cloned())363	}364365	fn get_lazy(&self, index: usize) -> Option<Thunk<Val>> {366		self.0.get(index).cloned().map(Thunk::evaluated)367	}368369	fn get_cheap(&self, index: usize) -> Option<Val> {370		self.0.get(index).cloned()371	}372}373impl From<EagerArray> for ArrValue {374	fn from(value: EagerArray) -> Self {375		Self::Eager(value)376	}377}378379/// Inclusive range type380#[derive(Debug, Trace, Clone, PartialEq, Eq)]381pub struct RangeArray {382	start: i32,383	end: i32,384}385impl RangeArray {386	pub fn empty() -> Self {387		Self::new_exclusive(0, 0)388	}389	pub fn new_exclusive(start: i32, end: i32) -> Self {390		end.checked_sub(1)391			.map_or_else(Self::empty, |end| Self { start, end })392	}393	pub fn new_inclusive(start: i32, end: i32) -> Self {394		Self { start, end }395	}396	fn range(&self) -> impl Iterator<Item = i32> + ExactSizeIterator + DoubleEndedIterator {397		WithExactSize(398			self.start..=self.end,399			(self.end as usize)400				.wrapping_sub(self.start as usize)401				.wrapping_add(1),402		)403	}404}405406impl ArrayLike for RangeArray {407	fn len(&self) -> usize {408		self.range().len()409	}410	fn is_empty(&self) -> bool {411		self.range().len() == 0412	}413414	fn get(&self, index: usize) -> Result<Option<Val>> {415		Ok(self.get_cheap(index))416	}417418	fn get_lazy(&self, index: usize) -> Option<Thunk<Val>> {419		self.get_cheap(index).map(Thunk::evaluated)420	}421422	fn get_cheap(&self, index: usize) -> Option<Val> {423		self.range().nth(index).map(|i| Val::Num(f64::from(i)))424	}425}426impl From<RangeArray> for ArrValue {427	fn from(value: RangeArray) -> Self {428		Self::Range(value)429	}430}431432#[derive(Debug, Trace, Clone)]433pub struct ReverseArray(pub ArrValue);434impl ArrayLike for ReverseArray {435	fn len(&self) -> usize {436		self.0.len()437	}438439	fn get(&self, index: usize) -> Result<Option<Val>> {440		self.0.get(self.0.len() - index - 1)441	}442443	fn get_lazy(&self, index: usize) -> Option<Thunk<Val>> {444		self.0.get_lazy(self.0.len() - index - 1)445	}446447	fn get_cheap(&self, index: usize) -> Option<Val> {448		self.0.get_cheap(self.0.len() - index - 1)449	}450	fn reverse(self) -> ArrValue {451		self.0452	}453}454impl From<ReverseArray> for ArrValue {455	fn from(value: ReverseArray) -> Self {456		Self::Reverse(Cc::new(value))457	}458}459460#[derive(Trace, Debug)]461pub struct MappedArrayInner {462	inner: ArrValue,463	cached: RefCell<Vec<ArrayThunk<()>>>,464	mapper: FuncVal,465}466#[derive(Trace, Debug, Clone)]467pub struct MappedArray(Cc<MappedArrayInner>);468impl MappedArray {469	pub fn new(inner: ArrValue, mapper: FuncVal) -> Self {470		let len = inner.len();471		Self(Cc::new(MappedArrayInner {472			inner,473			cached: RefCell::new(vec![ArrayThunk::Waiting(()); len]),474			mapper,475		}))476	}477}478impl ArrayLike for MappedArray {479	fn len(&self) -> usize {480		self.0.cached.borrow().len()481	}482483	fn get(&self, index: usize) -> Result<Option<Val>> {484		if index >= self.len() {485			return Ok(None);486		}487		match &self.0.cached.borrow()[index] {488			ArrayThunk::Computed(c) => return Ok(Some(c.clone())),489			ArrayThunk::Errored(e) => return Err(e.clone()),490			ArrayThunk::Pending => return Err(InfiniteRecursionDetected.into()),491			ArrayThunk::Waiting(..) => {}492		};493494		let ArrayThunk::Waiting(_) =495			replace(&mut self.0.cached.borrow_mut()[index], ArrayThunk::Pending)496		else {497			unreachable!()498		};499500		let val = self501			.0502			.inner503			.get(index)504			.transpose()505			.expect("index checked")506			.and_then(|r| self.0.mapper.evaluate_simple(&(r,), false));507508		let new_value = match val {509			Ok(v) => v,510			Err(e) => {511				self.0.cached.borrow_mut()[index] = ArrayThunk::Errored(e.clone());512				return Err(e);513			}514		};515		self.0.cached.borrow_mut()[index] = ArrayThunk::Computed(new_value.clone());516		Ok(Some(new_value))517	}518	fn get_lazy(&self, index: usize) -> Option<Thunk<Val>> {519		#[derive(Trace)]520		struct ArrayElement {521			arr_thunk: MappedArray,522			index: usize,523		}524525		impl ThunkValue for ArrayElement {526			type Output = Val;527528			fn get(self: Box<Self>) -> Result<Self::Output> {529				self.arr_thunk530					.get(self.index)531					.transpose()532					.expect("index checked")533			}534		}535536		if index >= self.len() {537			return None;538		}539		match &self.0.cached.borrow()[index] {540			ArrayThunk::Computed(c) => return Some(Thunk::evaluated(c.clone())),541			ArrayThunk::Errored(e) => return Some(Thunk::errored(e.clone())),542			ArrayThunk::Waiting(_) | ArrayThunk::Pending => {}543		};544545		Some(Thunk::new(ArrayElement {546			arr_thunk: self.clone(),547			index,548		}))549	}550551	fn get_cheap(&self, _index: usize) -> Option<Val> {552		None553	}554}555impl From<MappedArray> for ArrValue {556	fn from(value: MappedArray) -> Self {557		Self::Mapped(value)558	}559}560561#[derive(Trace, Debug)]562pub struct RepeatedArrayInner {563	data: ArrValue,564	repeats: usize,565	total_len: usize,566}567#[derive(Trace, Debug, Clone)]568pub struct RepeatedArray(Cc<RepeatedArrayInner>);569impl RepeatedArray {570	pub fn new(data: ArrValue, repeats: usize) -> Option<Self> {571		let total_len = data.len().checked_mul(repeats)?;572		Some(Self(Cc::new(RepeatedArrayInner {573			data,574			repeats,575			total_len,576		})))577	}578	pub fn is_cheap(&self) -> bool {579		self.0.data.is_cheap()580	}581}582583impl ArrayLike for RepeatedArray {584	fn len(&self) -> usize {585		self.0.total_len586	}587588	fn get(&self, index: usize) -> Result<Option<Val>> {589		if index > self.0.total_len {590			return Ok(None);591		}592		self.0.data.get(index % self.0.data.len())593	}594595	fn get_lazy(&self, index: usize) -> Option<Thunk<Val>> {596		if index > self.0.total_len {597			return None;598		}599		self.0.data.get_lazy(index % self.0.data.len())600	}601602	fn get_cheap(&self, index: usize) -> Option<Val> {603		if index > self.0.total_len {604			return None;605		}606		self.0.data.get_cheap(index % self.0.data.len())607	}608}609impl From<RepeatedArray> for ArrValue {610	fn from(value: RepeatedArray) -> Self {611		Self::Repeated(value)612	}613}614615macro_rules! pass {616	($t:ident.$m:ident($($ident:ident),*)) => {617		match $t {618			Self::Bytes(e) => e.$m($($ident)*),619			Self::Chars(e) => e.$m($($ident)*),620			Self::Expr(e) => e.$m($($ident)*),621			Self::Lazy(e) => e.$m($($ident)*),622			Self::Eager(e) => e.$m($($ident)*),623			Self::Range(e) => e.$m($($ident)*),624			Self::Slice(e) => e.$m($($ident)*),625			Self::Extended(e) => e.$m($($ident)*),626			Self::Reverse(e) => e.$m($($ident)*),627			Self::Mapped(e) => e.$m($($ident)*),628			Self::Repeated(e) => e.$m($($ident)*),629		}630	};631}632pub(super) use pass;
modifiedcrates/jrsonnet-evaluator/src/manifest.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/manifest.rs
+++ b/crates/jrsonnet-evaluator/src/manifest.rs
@@ -276,7 +276,10 @@
 impl ManifestFormat for StringFormat {
 	fn manifest_buf(&self, val: Val, out: &mut String) -> Result<()> {
 		let Val::Str(s) = val else {
-			throw!("output should be string for string manifest format, got {}", val.value_type())
+			throw!(
+				"output should be string for string manifest format, got {}",
+				val.value_type()
+			)
 		};
 		write!(out, "{s}").unwrap();
 		Ok(())
@@ -290,7 +293,10 @@
 impl<I: ManifestFormat> ManifestFormat for YamlStreamFormat<I> {
 	fn manifest_buf(&self, val: Val, out: &mut String) -> Result<()> {
 		let Val::Arr(arr) = val else {
-			throw!("output should be array for yaml stream format, got {}", val.value_type())
+			throw!(
+				"output should be array for yaml stream format, got {}",
+				val.value_type()
+			)
 		};
 		if !arr.is_empty() {
 			for v in arr.iter() {
modifiedcrates/jrsonnet-evaluator/src/val.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/val.rs
+++ b/crates/jrsonnet-evaluator/src/val.rs
@@ -72,7 +72,8 @@
 			ThunkInner::Pending => return Err(InfiniteRecursionDetected.into()),
 			ThunkInner::Waiting(..) => (),
 		};
-		let ThunkInner::Waiting(value) = replace(&mut *self.0.borrow_mut(), ThunkInner::Pending) else {
+		let ThunkInner::Waiting(value) = replace(&mut *self.0.borrow_mut(), ThunkInner::Pending)
+		else {
 			unreachable!();
 		};
 		let new_value = match value.0.get() {
modifiedcrates/jrsonnet-macros/src/lib.rsdiffbeforeafterboth
--- a/crates/jrsonnet-macros/src/lib.rs
+++ b/crates/jrsonnet-macros/src/lib.rs
@@ -51,7 +51,7 @@
 
 fn extract_type_from_option(ty: &Type) -> Result<Option<&Type>> {
 	let Some(args) = type_is_path(ty, "Option") else {
-		return Ok(None)
+		return Ok(None);
 	};
 	// It should have only on angle-bracketed param ("<String>"):
 	let PathArguments::AngleBracketed(params) = args else {
@@ -63,7 +63,7 @@
 		return Err(Error::new(
 			generic_arg.span(),
 			"option generic should be a type",
-		))
+		));
 	};
 	Ok(Some(ty))
 }
@@ -210,7 +210,7 @@
 		return Err(Error::new(
 			fun.sig.span(),
 			"builtin should return something",
-		))
+		));
 	};
 
 	let name = fun.sig.ident.to_string();
modifiedcrates/jrsonnet-parser/src/lib.rsdiffbeforeafterboth
--- a/crates/jrsonnet-parser/src/lib.rs
+++ b/crates/jrsonnet-parser/src/lib.rs
@@ -630,7 +630,7 @@
 					el!(
 						Apply(
 							el!(
-								Index{
+								Index {
 									indexable: el!(Var("std".into()), 1, 4),
 									index: el!(Str("deepJoin".into()), 5, 13),
 									#[cfg(feature = "exp-null-coaelse")]
modifiedcrates/jrsonnet-parser/src/source.rsdiffbeforeafterboth
--- a/crates/jrsonnet-parser/src/source.rs
+++ b/crates/jrsonnet-parser/src/source.rs
@@ -33,7 +33,7 @@
 		}
 		fn dyn_eq(&self, other: &dyn $T) -> bool {
 			let Some(other) = other.as_any().downcast_ref::<Self>() else {
-				return false
+				return false;
 			};
 			let this = <Self as $T>::as_any(self)
 				.downcast_ref::<Self>()
modifiedflake.lockdiffbeforeafterboth
--- a/flake.lock
+++ b/flake.lock
@@ -20,11 +20,11 @@
     },
     "nixpkgs": {
       "locked": {
-        "lastModified": 1689162265,
-        "narHash": "sha256-kdW79sfwX2TTX8yFBNUsEYOG+gQuAOHU+WcUtxMUnlc=",
+        "lastModified": 1690394427,
+        "narHash": "sha256-ZT1ABAZVdJycCJMUHu533dvcMuxqUGDnp6N2zLcFrv4=",
         "owner": "nixos",
         "repo": "nixpkgs",
-        "rev": "1941c7d8f1219c615a1d6dae826e0d6fab89acca",
+        "rev": "78df3591ec67310b8cc4b753e1496999da2678cf",
         "type": "github"
       },
       "original": {
@@ -50,11 +50,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1689129196,
-        "narHash": "sha256-/z/Al4sFcIh5oPQWA9MclQmJR9g3RO8UDiHGaj/T9R8=",
+        "lastModified": 1690338181,
+        "narHash": "sha256-Sz2oQ9aNS3MVncnCMndr0302G26UrFUfPynoH2iLjsg=",
         "owner": "oxalica",
         "repo": "rust-overlay",
-        "rev": "db8d909c9526d4406579ee7343bf2d7de3d15eac",
+        "rev": "b7f0b7b58b3c6f14a1377ec31a3d78b23ab843ec",
         "type": "github"
       },
       "original": {
modifiedflake.nixdiffbeforeafterboth
--- a/flake.nix
+++ b/flake.nix
@@ -16,7 +16,7 @@
           inherit system;
           overlays = [ rust-overlay.overlays.default ];
         };
-        rust = ((pkgs.rustChannelOf { date = "2023-06-26"; channel = "nightly"; }).default.override {
+        rust = ((pkgs.rustChannelOf { date = "2023-07-23"; channel = "nightly"; }).default.override {
           extensions = [ "rust-src" "miri" "rust-analyzer" ];
         });
       in