git.delta.rocks / jrsonnet / refs/commits / 420d09ae14f6

difftreelog

feat impl ArgsLike for Vec<Val>

Yaroslav Bolyukin2022-10-11parent: #e8ba764.patch.diff
in: master

1 file changed

modifiedcrates/jrsonnet-evaluator/src/function/arglike.rsdiffbeforeafterboth
before · crates/jrsonnet-evaluator/src/function/arglike.rs
1use std::collections::HashMap;23use jrsonnet_gcmodule::Trace;4use jrsonnet_interner::IStr;5use jrsonnet_parser::{ArgsDesc, LocExpr};67use crate::{8	error::Result, evaluate, tb, typed::Typed, val::ThunkValue, Context, State, Thunk, Val,9};1011#[derive(Trace)]12struct EvaluateThunk {13	ctx: Context,14	expr: LocExpr,15}16impl ThunkValue for EvaluateThunk {17	type Output = Val;18	fn get(self: Box<Self>, s: State) -> Result<Val> {19		evaluate(s, self.ctx, &self.expr)20	}21}2223pub trait ArgLike {24	fn evaluate_arg(&self, s: State, ctx: Context, tailstrict: bool) -> Result<Thunk<Val>>;25}2627impl ArgLike for &LocExpr {28	fn evaluate_arg(&self, s: State, ctx: Context, tailstrict: bool) -> Result<Thunk<Val>> {29		Ok(if tailstrict {30			Thunk::evaluated(evaluate(s, ctx, self)?)31		} else {32			Thunk::new(tb!(EvaluateThunk {33				ctx,34				expr: (*self).clone(),35			}))36		})37	}38}3940impl<T> ArgLike for T41where42	T: Typed + Clone,43{44	fn evaluate_arg(&self, s: State, _ctx: Context, _tailstrict: bool) -> Result<Thunk<Val>> {45		let val = T::into_untyped(self.clone(), s)?;46		Ok(Thunk::evaluated(val))47	}48}4950#[derive(Clone)]51pub enum TlaArg {52	String(IStr),53	Code(LocExpr),54	Val(Val),55}56impl ArgLike for TlaArg {57	fn evaluate_arg(&self, s: State, ctx: Context, tailstrict: bool) -> Result<Thunk<Val>> {58		match self {59			TlaArg::String(s) => Ok(Thunk::evaluated(Val::Str(s.clone()))),60			TlaArg::Code(code) => Ok(if tailstrict {61				Thunk::evaluated(evaluate(s, ctx, code)?)62			} else {63				Thunk::new(tb!(EvaluateThunk {64					ctx,65					expr: code.clone(),66				}))67			}),68			TlaArg::Val(val) => Ok(Thunk::evaluated(val.clone())),69		}70	}71}7273mod sealed {74	/// Implemented for `ArgsLike`, where only unnamed arguments present75	pub trait Unnamed {}76	/// Implemented for `ArgsLike`, where only named arguments present77	pub trait Named {}78}7980pub trait ArgsLike {81	fn unnamed_len(&self) -> usize;82	fn unnamed_iter(83		&self,84		s: State,85		ctx: Context,86		tailstrict: bool,87		handler: &mut dyn FnMut(usize, Thunk<Val>) -> Result<()>,88	) -> Result<()>;89	fn named_iter(90		&self,91		s: State,92		ctx: Context,93		tailstrict: bool,94		handler: &mut dyn FnMut(&IStr, Thunk<Val>) -> Result<()>,95	) -> Result<()>;96	fn named_names(&self, handler: &mut dyn FnMut(&IStr));97}9899impl ArgsLike for ArgsDesc {100	fn unnamed_len(&self) -> usize {101		self.unnamed.len()102	}103104	fn unnamed_iter(105		&self,106		s: State,107		ctx: Context,108		tailstrict: bool,109		handler: &mut dyn FnMut(usize, Thunk<Val>) -> Result<()>,110	) -> Result<()> {111		for (id, arg) in self.unnamed.iter().enumerate() {112			handler(113				id,114				if tailstrict {115					Thunk::evaluated(evaluate(s.clone(), ctx.clone(), arg)?)116				} else {117					Thunk::new(tb!(EvaluateThunk {118						ctx: ctx.clone(),119						expr: arg.clone(),120					}))121				},122			)?;123		}124		Ok(())125	}126127	fn named_iter(128		&self,129		s: State,130		ctx: Context,131		tailstrict: bool,132		handler: &mut dyn FnMut(&IStr, Thunk<Val>) -> Result<()>,133	) -> Result<()> {134		for (name, arg) in &self.named {135			handler(136				name,137				if tailstrict {138					Thunk::evaluated(evaluate(s.clone(), ctx.clone(), arg)?)139				} else {140					Thunk::new(tb!(EvaluateThunk {141						ctx: ctx.clone(),142						expr: arg.clone(),143					}))144				},145			)?;146		}147		Ok(())148	}149150	fn named_names(&self, handler: &mut dyn FnMut(&IStr)) {151		for (name, _) in &self.named {152			handler(name);153		}154	}155}156157impl<A: ArgLike, S> sealed::Named for HashMap<IStr, A, S> {}158impl<A: ArgLike, S> ArgsLike for HashMap<IStr, A, S> {159	fn unnamed_len(&self) -> usize {160		0161	}162163	fn unnamed_iter(164		&self,165		_s: State,166		_ctx: Context,167		_tailstrict: bool,168		_handler: &mut dyn FnMut(usize, Thunk<Val>) -> Result<()>,169	) -> Result<()> {170		Ok(())171	}172173	fn named_iter(174		&self,175		s: State,176		ctx: Context,177		tailstrict: bool,178		handler: &mut dyn FnMut(&IStr, Thunk<Val>) -> Result<()>,179	) -> Result<()> {180		for (name, value) in self.iter() {181			handler(182				name,183				value.evaluate_arg(s.clone(), ctx.clone(), tailstrict)?,184			)?;185		}186		Ok(())187	}188189	fn named_names(&self, handler: &mut dyn FnMut(&IStr)) {190		for (name, _) in self.iter() {191			handler(name);192		}193	}194}195196macro_rules! impl_args_like {197	($count:expr; $($gen:ident)*) => {198		impl<$($gen: ArgLike,)*> sealed::Unnamed for ($($gen,)*) {}199		impl<$($gen: ArgLike,)*> ArgsLike for ($($gen,)*) {200			fn unnamed_len(&self) -> usize {201				$count202			}203			#[allow(non_snake_case, unused_assignments)]204			fn unnamed_iter(205				&self,206				s: State,207				ctx: Context,208				tailstrict: bool,209				handler: &mut dyn FnMut(usize, Thunk<Val>) -> Result<()>,210			) -> Result<()> {211				let mut i = 0usize;212				let ($($gen,)*) = self;213				$(214					handler(i, $gen.evaluate_arg(s.clone(), ctx.clone(), tailstrict)?)?;215					i+=1;216				)*217				Ok(())218			}219			fn named_iter(220				&self,221				_s: State,222				_ctx: Context,223				_tailstrict: bool,224				_handler: &mut dyn FnMut(&IStr, Thunk<Val>) -> Result<()>,225			) -> Result<()> {226				Ok(())227			}228			fn named_names(&self, _handler: &mut dyn FnMut(&IStr)) {}229		}230		impl<$($gen: ArgLike,)*> sealed::Named for ($((IStr, $gen),)*) {}231		impl<$($gen: ArgLike,)*> ArgsLike for ($((IStr, $gen),)*) {232			fn unnamed_len(&self) -> usize {233				0234			}235			fn unnamed_iter(236				&self,237				_s: State,238				_ctx: Context,239				_tailstrict: bool,240				_handler: &mut dyn FnMut(usize, Thunk<Val>) -> Result<()>,241			) -> Result<()> {242				Ok(())243			}244			#[allow(non_snake_case)]245			fn named_iter(246				&self,247				s: State,248				ctx: Context,249				tailstrict: bool,250				handler: &mut dyn FnMut(&IStr, Thunk<Val>) -> Result<()>,251			) -> Result<()> {252				let ($($gen,)*) = self;253				$(254					handler(&$gen.0, $gen.1.evaluate_arg(s.clone(), ctx.clone(), tailstrict)?)?;255				)*256				Ok(())257			}258			#[allow(non_snake_case)]259			fn named_names(&self, handler: &mut dyn FnMut(&IStr)) {260				let ($($gen,)*) = self;261				$(262					handler(&$gen.0);263				)*264			}265		}266	};267	($count:expr; $($cur:ident)* @ $c:ident $($rest:ident)*) => {268		impl_args_like!($count; $($cur)*);269		impl_args_like!($count + 1usize; $($cur)* $c @ $($rest)*);270	};271	($count:expr; $($cur:ident)* @) => {272		impl_args_like!($count; $($cur)*);273	}274}275impl_args_like! {276	// First argument is already in position, so count starts from 1277	1usize; A @ B C D E F G H I J K L278}279280impl ArgsLike for () {281	fn unnamed_len(&self) -> usize {282		0283	}284285	fn unnamed_iter(286		&self,287		_s: State,288		_ctx: Context,289		_tailstrict: bool,290		_handler: &mut dyn FnMut(usize, Thunk<Val>) -> Result<()>,291	) -> Result<()> {292		Ok(())293	}294295	fn named_iter(296		&self,297		_s: State,298		_ctx: Context,299		_tailstrict: bool,300		_handler: &mut dyn FnMut(&IStr, Thunk<Val>) -> Result<()>,301	) -> Result<()> {302		Ok(())303	}304305	fn named_names(&self, _handler: &mut dyn FnMut(&IStr)) {}306}
after · crates/jrsonnet-evaluator/src/function/arglike.rs
1use std::collections::HashMap;23use jrsonnet_gcmodule::Trace;4use jrsonnet_interner::IStr;5use jrsonnet_parser::{ArgsDesc, LocExpr};67use crate::{8	error::Result, evaluate, tb, typed::Typed, val::ThunkValue, Context, State, Thunk, Val,9};1011#[derive(Trace)]12struct EvaluateThunk {13	ctx: Context,14	expr: LocExpr,15}16impl ThunkValue for EvaluateThunk {17	type Output = Val;18	fn get(self: Box<Self>, s: State) -> Result<Val> {19		evaluate(s, self.ctx, &self.expr)20	}21}2223pub trait ArgLike {24	fn evaluate_arg(&self, s: State, ctx: Context, tailstrict: bool) -> Result<Thunk<Val>>;25}2627impl ArgLike for &LocExpr {28	fn evaluate_arg(&self, s: State, ctx: Context, tailstrict: bool) -> Result<Thunk<Val>> {29		Ok(if tailstrict {30			Thunk::evaluated(evaluate(s, ctx, self)?)31		} else {32			Thunk::new(tb!(EvaluateThunk {33				ctx,34				expr: (*self).clone(),35			}))36		})37	}38}3940impl<T> ArgLike for T41where42	T: Typed + Clone,43{44	fn evaluate_arg(&self, s: State, _ctx: Context, _tailstrict: bool) -> Result<Thunk<Val>> {45		let val = T::into_untyped(self.clone(), s)?;46		Ok(Thunk::evaluated(val))47	}48}4950#[derive(Clone)]51pub enum TlaArg {52	String(IStr),53	Code(LocExpr),54	Val(Val),55}56impl ArgLike for TlaArg {57	fn evaluate_arg(&self, s: State, ctx: Context, tailstrict: bool) -> Result<Thunk<Val>> {58		match self {59			TlaArg::String(s) => Ok(Thunk::evaluated(Val::Str(s.clone()))),60			TlaArg::Code(code) => Ok(if tailstrict {61				Thunk::evaluated(evaluate(s, ctx, code)?)62			} else {63				Thunk::new(tb!(EvaluateThunk {64					ctx,65					expr: code.clone(),66				}))67			}),68			TlaArg::Val(val) => Ok(Thunk::evaluated(val.clone())),69		}70	}71}7273mod sealed {74	/// Implemented for `ArgsLike`, where only unnamed arguments present75	pub trait Unnamed {}76	/// Implemented for `ArgsLike`, where only named arguments present77	pub trait Named {}78}7980pub trait ArgsLike {81	fn unnamed_len(&self) -> usize;82	fn unnamed_iter(83		&self,84		s: State,85		ctx: Context,86		tailstrict: bool,87		handler: &mut dyn FnMut(usize, Thunk<Val>) -> Result<()>,88	) -> Result<()>;89	fn named_iter(90		&self,91		s: State,92		ctx: Context,93		tailstrict: bool,94		handler: &mut dyn FnMut(&IStr, Thunk<Val>) -> Result<()>,95	) -> Result<()>;96	fn named_names(&self, handler: &mut dyn FnMut(&IStr));97}9899impl ArgsLike for Vec<Val> {100	fn unnamed_len(&self) -> usize {101		self.len()102	}103	fn unnamed_iter(104		&self,105		_s: State,106		_ctx: Context,107		_tailstrict: bool,108		handler: &mut dyn FnMut(usize, Thunk<Val>) -> Result<()>,109	) -> Result<()> {110		for (idx, el) in self.iter().enumerate() {111			handler(idx, Thunk::evaluated(el.clone()))?112		}113		Ok(())114	}115	fn named_iter(116		&self,117		_s: State,118		_ctx: Context,119		_tailstrict: bool,120		_handler: &mut dyn FnMut(&IStr, Thunk<Val>) -> Result<()>,121	) -> Result<()> {122		Ok(())123	}124	fn named_names(&self, _handler: &mut dyn FnMut(&IStr)) {}125}126127impl ArgsLike for ArgsDesc {128	fn unnamed_len(&self) -> usize {129		self.unnamed.len()130	}131132	fn unnamed_iter(133		&self,134		s: State,135		ctx: Context,136		tailstrict: bool,137		handler: &mut dyn FnMut(usize, Thunk<Val>) -> Result<()>,138	) -> Result<()> {139		for (id, arg) in self.unnamed.iter().enumerate() {140			handler(141				id,142				if tailstrict {143					Thunk::evaluated(evaluate(s.clone(), ctx.clone(), arg)?)144				} else {145					Thunk::new(tb!(EvaluateThunk {146						ctx: ctx.clone(),147						expr: arg.clone(),148					}))149				},150			)?;151		}152		Ok(())153	}154155	fn named_iter(156		&self,157		s: State,158		ctx: Context,159		tailstrict: bool,160		handler: &mut dyn FnMut(&IStr, Thunk<Val>) -> Result<()>,161	) -> Result<()> {162		for (name, arg) in &self.named {163			handler(164				name,165				if tailstrict {166					Thunk::evaluated(evaluate(s.clone(), ctx.clone(), arg)?)167				} else {168					Thunk::new(tb!(EvaluateThunk {169						ctx: ctx.clone(),170						expr: arg.clone(),171					}))172				},173			)?;174		}175		Ok(())176	}177178	fn named_names(&self, handler: &mut dyn FnMut(&IStr)) {179		for (name, _) in &self.named {180			handler(name);181		}182	}183}184185impl<A: ArgLike, S> sealed::Named for HashMap<IStr, A, S> {}186impl<A: ArgLike, S> ArgsLike for HashMap<IStr, A, S> {187	fn unnamed_len(&self) -> usize {188		0189	}190191	fn unnamed_iter(192		&self,193		_s: State,194		_ctx: Context,195		_tailstrict: bool,196		_handler: &mut dyn FnMut(usize, Thunk<Val>) -> Result<()>,197	) -> Result<()> {198		Ok(())199	}200201	fn named_iter(202		&self,203		s: State,204		ctx: Context,205		tailstrict: bool,206		handler: &mut dyn FnMut(&IStr, Thunk<Val>) -> Result<()>,207	) -> Result<()> {208		for (name, value) in self.iter() {209			handler(210				name,211				value.evaluate_arg(s.clone(), ctx.clone(), tailstrict)?,212			)?;213		}214		Ok(())215	}216217	fn named_names(&self, handler: &mut dyn FnMut(&IStr)) {218		for (name, _) in self.iter() {219			handler(name);220		}221	}222}223224macro_rules! impl_args_like {225	($count:expr; $($gen:ident)*) => {226		impl<$($gen: ArgLike,)*> sealed::Unnamed for ($($gen,)*) {}227		impl<$($gen: ArgLike,)*> ArgsLike for ($($gen,)*) {228			fn unnamed_len(&self) -> usize {229				$count230			}231			#[allow(non_snake_case, unused_assignments)]232			fn unnamed_iter(233				&self,234				s: State,235				ctx: Context,236				tailstrict: bool,237				handler: &mut dyn FnMut(usize, Thunk<Val>) -> Result<()>,238			) -> Result<()> {239				let mut i = 0usize;240				let ($($gen,)*) = self;241				$(242					handler(i, $gen.evaluate_arg(s.clone(), ctx.clone(), tailstrict)?)?;243					i+=1;244				)*245				Ok(())246			}247			fn named_iter(248				&self,249				_s: State,250				_ctx: Context,251				_tailstrict: bool,252				_handler: &mut dyn FnMut(&IStr, Thunk<Val>) -> Result<()>,253			) -> Result<()> {254				Ok(())255			}256			fn named_names(&self, _handler: &mut dyn FnMut(&IStr)) {}257		}258		impl<$($gen: ArgLike,)*> sealed::Named for ($((IStr, $gen),)*) {}259		impl<$($gen: ArgLike,)*> ArgsLike for ($((IStr, $gen),)*) {260			fn unnamed_len(&self) -> usize {261				0262			}263			fn unnamed_iter(264				&self,265				_s: State,266				_ctx: Context,267				_tailstrict: bool,268				_handler: &mut dyn FnMut(usize, Thunk<Val>) -> Result<()>,269			) -> Result<()> {270				Ok(())271			}272			#[allow(non_snake_case)]273			fn named_iter(274				&self,275				s: State,276				ctx: Context,277				tailstrict: bool,278				handler: &mut dyn FnMut(&IStr, Thunk<Val>) -> Result<()>,279			) -> Result<()> {280				let ($($gen,)*) = self;281				$(282					handler(&$gen.0, $gen.1.evaluate_arg(s.clone(), ctx.clone(), tailstrict)?)?;283				)*284				Ok(())285			}286			#[allow(non_snake_case)]287			fn named_names(&self, handler: &mut dyn FnMut(&IStr)) {288				let ($($gen,)*) = self;289				$(290					handler(&$gen.0);291				)*292			}293		}294	};295	($count:expr; $($cur:ident)* @ $c:ident $($rest:ident)*) => {296		impl_args_like!($count; $($cur)*);297		impl_args_like!($count + 1usize; $($cur)* $c @ $($rest)*);298	};299	($count:expr; $($cur:ident)* @) => {300		impl_args_like!($count; $($cur)*);301	}302}303impl_args_like! {304	// First argument is already in position, so count starts from 1305	1usize; A @ B C D E F G H I J K L306}307308impl ArgsLike for () {309	fn unnamed_len(&self) -> usize {310		0311	}312313	fn unnamed_iter(314		&self,315		_s: State,316		_ctx: Context,317		_tailstrict: bool,318		_handler: &mut dyn FnMut(usize, Thunk<Val>) -> Result<()>,319	) -> Result<()> {320		Ok(())321	}322323	fn named_iter(324		&self,325		_s: State,326		_ctx: Context,327		_tailstrict: bool,328		_handler: &mut dyn FnMut(&IStr, Thunk<Val>) -> Result<()>,329	) -> Result<()> {330		Ok(())331	}332333	fn named_names(&self, _handler: &mut dyn FnMut(&IStr)) {}334}