git.delta.rocks / jrsonnet / refs/commits / 6d535da7fe1f

difftreelog

style fix clippy warnings

Yaroslav Bolyukin2021-07-06parent: #e668bf3.patch.diff
in: master

5 files changed

modifiedcrates/jrsonnet-evaluator/src/builtin/mod.rsdiffbeforeafterboth
before · crates/jrsonnet-evaluator/src/builtin/mod.rs
1use crate::{2	equals,3	error::{Error::*, Result},4	operator::evaluate_mod_op,5	parse_args, primitive_equals, push, throw, with_state, ArrValue, Context, EvaluationState,6	FuncVal, IndexableVal, LazyVal, Val,7};8use format::{format_arr, format_obj};9use jrsonnet_gc::Gc;10use jrsonnet_interner::IStr;11use jrsonnet_parser::{ArgsDesc, ExprLocation};12use jrsonnet_types::ty;13use std::{collections::HashMap, path::PathBuf, rc::Rc};1415pub mod stdlib;16pub use stdlib::*;1718use self::manifest::{escape_string_json, manifest_json_ex, ManifestJsonOptions, ManifestType};1920pub mod format;21pub mod manifest;22pub mod sort;2324pub fn std_format(str: IStr, vals: Val) -> Result<Val> {25	push(26		Some(&ExprLocation(Rc::from(PathBuf::from("std.jsonnet")), 0, 0)),27		|| format!("std.format of {}", str),28		|| {29			Ok(match vals {30				Val::Arr(vals) => Val::Str(format_arr(&str, &vals.evaluated()?)?.into()),31				Val::Obj(obj) => Val::Str(format_obj(&str, &obj)?.into()),32				o => Val::Str(format_arr(&str, &[o])?.into()),33			})34		},35	)36}3738pub fn std_slice(39	indexable: IndexableVal,40	index: Option<usize>,41	end: Option<usize>,42	step: Option<usize>,43) -> Result<Val> {44	let index = index.unwrap_or(0);45	let end = end.unwrap_or_else(|| match &indexable {46		IndexableVal::Str(_) => usize::MAX,47		IndexableVal::Arr(v) => v.len(),48	});49	let step = step.unwrap_or(1);50	match &indexable {51		IndexableVal::Str(s) => Ok(Val::Str(52			(s.chars()53				.skip(index)54				.take(end - index)55				.step_by(step)56				.collect::<String>())57			.into(),58		)),59		IndexableVal::Arr(arr) => Ok(Val::Arr(60			(arr.iter()61				.skip(index)62				.take(end - index)63				.step_by(step)64				.collect::<Result<Vec<Val>>>()?)65			.into(),66		)),67	}68}6970type Builtin = fn(context: Context, loc: Option<&ExprLocation>, args: &ArgsDesc) -> Result<Val>;7172type BuiltinsType = HashMap<Box<str>, Builtin>;7374thread_local! {75	static BUILTINS: BuiltinsType = {76		[77			("length".into(), builtin_length as Builtin),78			("type".into(), builtin_type),79			("makeArray".into(), builtin_make_array),80			("codepoint".into(), builtin_codepoint),81			("objectFieldsEx".into(), builtin_object_fields_ex),82			("objectHasEx".into(), builtin_object_has_ex),83			("slice".into(), builtin_slice),84			("primitiveEquals".into(), builtin_primitive_equals),85			("equals".into(), builtin_equals),86			("modulo".into(), builtin_modulo),87			("mod".into(), builtin_mod),88			("floor".into(), builtin_floor),89			("log".into(), builtin_log),90			("pow".into(), builtin_pow),91			("extVar".into(), builtin_ext_var),92			("native".into(), builtin_native),93			("filter".into(), builtin_filter),94			("map".into(), builtin_map),95			("foldl".into(), builtin_foldl),96			("foldr".into(), builtin_foldr),97			("sortImpl".into(), builtin_sort_impl),98			("format".into(), builtin_format),99			("range".into(), builtin_range),100			("char".into(), builtin_char),101			("encodeUTF8".into(), builtin_encode_utf8),102			("md5".into(), builtin_md5),103			("base64".into(), builtin_base64),104			("trace".into(), builtin_trace),105			("join".into(), builtin_join),106			("escapeStringJson".into(), builtin_escape_string_json),107			("manifestJsonEx".into(), builtin_manifest_json_ex),108			("reverse".into(), builtin_reverse),109			("id".into(), builtin_id),110			("strReplace".into(), builtin_str_replace),111			("parseJson".into(), builtin_parse_json),112		].iter().cloned().collect()113	};114}115116fn builtin_length(context: Context, _loc: Option<&ExprLocation>, args: &ArgsDesc) -> Result<Val> {117	parse_args!(context, "length", args, 1, [118		0, x: ty!((string | object | array));119	], {120		Ok(match x {121			Val::Str(n) => Val::Num(n.chars().count() as f64),122			Val::Arr(a) => Val::Num(a.len() as f64),123			Val::Obj(o) => Val::Num(124				o.fields_visibility()125					.into_iter()126					.filter(|(_k, v)| *v)127					.count() as f64,128			),129			_ => unreachable!(),130		})131	})132}133134fn builtin_type(context: Context, _loc: Option<&ExprLocation>, args: &ArgsDesc) -> Result<Val> {135	parse_args!(context, "type", args, 1, [136		0, x: ty!(any);137	], {138		Ok(Val::Str(x.value_type().name().into()))139	})140}141142fn builtin_make_array(143	context: Context,144	_loc: Option<&ExprLocation>,145	args: &ArgsDesc,146) -> Result<Val> {147	parse_args!(context, "makeArray", args, 2, [148		0, sz: ty!(BoundedNumber<(Some(0.0)), (None)>) => Val::Num;149		1, func: ty!(function) => Val::Func;150	], {151		let mut out = Vec::with_capacity(sz as usize);152		for i in 0..sz as usize {153			out.push(LazyVal::new_resolved(func.evaluate_values(154				context.clone(),155				&[Val::Num(i as f64)]156			)?))157		}158		Ok(Val::Arr(out.into()))159	})160}161162fn builtin_codepoint(163	context: Context,164	_loc: Option<&ExprLocation>,165	args: &ArgsDesc,166) -> Result<Val> {167	parse_args!(context, "codepoint", args, 1, [168		0, str: ty!(char) => Val::Str;169	], {170		Ok(Val::Num(str.chars().next().unwrap() as u32 as f64))171	})172}173174fn builtin_object_fields_ex(175	context: Context,176	_loc: Option<&ExprLocation>,177	args: &ArgsDesc,178) -> Result<Val> {179	parse_args!(context, "objectFieldsEx", args, 2, [180		0, obj: ty!(object) => Val::Obj;181		1, inc_hidden: ty!(boolean) => Val::Bool;182	], {183		let out = obj.fields_ex(inc_hidden);184		Ok(Val::Arr(out.into_iter().map(Val::Str).collect::<Vec<_>>().into()))185	})186}187188fn builtin_object_has_ex(189	context: Context,190	_loc: Option<&ExprLocation>,191	args: &ArgsDesc,192) -> Result<Val> {193	parse_args!(context, "objectHasEx", args, 3, [194		0, obj: ty!(object) => Val::Obj;195		1, f: ty!(string) => Val::Str;196		2, inc_hidden: ty!(boolean) => Val::Bool;197	], {198		Ok(Val::Bool(obj.has_field_ex(f, inc_hidden)))199	})200}201202fn builtin_parse_json(203	context: Context,204	_loc: Option<&ExprLocation>,205	args: &ArgsDesc,206) -> Result<Val> {207	parse_args!(context, "parseJson", args, 1, [208		0, s: ty!(string) => Val::Str;209	], {210		let state = EvaluationState::default();211		let path = PathBuf::from("std.parseJson").into();212		state.evaluate_snippet_raw(path ,s)213	})214}215216fn builtin_slice(context: Context, _loc: Option<&ExprLocation>, args: &ArgsDesc) -> Result<Val> {217	parse_args!(context, "slice", args, 4, [218		0, indexable: ty!((string | array));219		1, index: ty!((number | null));220		2, end: ty!((number | null));221		3, step: ty!((number | null));222	], {223		std_slice(224			indexable.to_indexable()?,225			index.try_cast_nullable_num("index")?.map(|v| v as usize),226			end.try_cast_nullable_num("end")?.map(|v| v as usize),227			step.try_cast_nullable_num("step")?.map(|v| v as usize),228		)229	})230}231232fn builtin_primitive_equals(233	context: Context,234	_loc: Option<&ExprLocation>,235	args: &ArgsDesc,236) -> Result<Val> {237	parse_args!(context, "primitiveEquals", args, 2, [238		0, a: ty!(any);239		1, b: ty!(any);240	], {241		Ok(Val::Bool(primitive_equals(&a, &b)?))242	})243}244245fn builtin_equals(context: Context, _loc: Option<&ExprLocation>, args: &ArgsDesc) -> Result<Val> {246	parse_args!(context, "equals", args, 2, [247		0, a: ty!(any);248		1, b: ty!(any);249	], {250		Ok(Val::Bool(equals(&a, &b)?))251	})252}253254fn builtin_modulo(context: Context, _loc: Option<&ExprLocation>, args: &ArgsDesc) -> Result<Val> {255	parse_args!(context, "modulo", args, 2, [256		0, a: ty!(number) => Val::Num;257		1, b: ty!(number) => Val::Num;258	], {259		Ok(Val::Num(a % b))260	})261}262263fn builtin_mod(context: Context, _loc: Option<&ExprLocation>, args: &ArgsDesc) -> Result<Val> {264	parse_args!(context, "mod", args, 2, [265		0, a: ty!((number | string));266		1, b: ty!(any);267	], {268		evaluate_mod_op(&a, &b)269	})270}271272fn builtin_floor(context: Context, _loc: Option<&ExprLocation>, args: &ArgsDesc) -> Result<Val> {273	parse_args!(context, "floor", args, 1, [274		0, x: ty!(number) => Val::Num;275	], {276		Ok(Val::Num(x.floor()))277	})278}279280fn builtin_log(context: Context, _loc: Option<&ExprLocation>, args: &ArgsDesc) -> Result<Val> {281	parse_args!(context, "log", args, 1, [282		0, n: ty!(number) => Val::Num;283	], {284		Ok(Val::Num(n.ln()))285	})286}287288fn builtin_pow(context: Context, _loc: Option<&ExprLocation>, args: &ArgsDesc) -> Result<Val> {289	parse_args!(context, "pow", args, 2, [290		0, x: ty!(number) => Val::Num;291		1, n: ty!(number) => Val::Num;292	], {293		Ok(Val::Num(x.powf(n)))294	})295}296297fn builtin_ext_var(context: Context, _loc: Option<&ExprLocation>, args: &ArgsDesc) -> Result<Val> {298	parse_args!(context, "extVar", args, 1, [299		0, x: ty!(string) => Val::Str;300	], {301		Ok(with_state(|s| s.settings().ext_vars.get(&x).cloned()).ok_or(UndefinedExternalVariable(x))?)302	})303}304305fn builtin_native(context: Context, _loc: Option<&ExprLocation>, args: &ArgsDesc) -> Result<Val> {306	parse_args!(context, "native", args, 1, [307		0, x: ty!(string) => Val::Str;308	], {309		Ok(with_state(|s| s.settings().ext_natives.get(&x).cloned()).map(|v| Val::Func(Gc::new(FuncVal::NativeExt(x.clone(), v)))).ok_or(UndefinedExternalFunction(x))?)310	})311}312313fn builtin_filter(context: Context, _loc: Option<&ExprLocation>, args: &ArgsDesc) -> Result<Val> {314	parse_args!(context, "filter", args, 2, [315		0, func: ty!(function) => Val::Func;316		1, arr: ty!(array) => Val::Arr;317	], {318		Ok(Val::Arr(arr.filter(|val| func319			.evaluate_values(context.clone(), &[val.clone()])?320			.try_cast_bool("filter predicate"))?))321	})322}323324fn builtin_map(context: Context, _loc: Option<&ExprLocation>, args: &ArgsDesc) -> Result<Val> {325	parse_args!(context, "map", args, 2, [326		0, func: ty!(function) => Val::Func;327		1, arr: ty!(array) => Val::Arr;328	], {329		Ok(Val::Arr(arr.map(|val| func330			.evaluate_values(context.clone(), &[val]))?))331	})332}333334fn builtin_foldl(context: Context, _loc: Option<&ExprLocation>, args: &ArgsDesc) -> Result<Val> {335	parse_args!(context, "foldl", args, 3, [336		0, func: ty!(function) => Val::Func;337		1, arr: ty!(array) => Val::Arr;338		2, init: ty!(any);339	], {340		let mut acc = init;341		for i in arr.iter() {342			acc = func.evaluate_values(context.clone(), &[acc, i?])?;343		}344		Ok(acc)345	})346}347348fn builtin_foldr(context: Context, _loc: Option<&ExprLocation>, args: &ArgsDesc) -> Result<Val> {349	parse_args!(context, "foldr", args, 3, [350		0, func: ty!(function) => Val::Func;351		1, arr: ty!(array) => Val::Arr;352		2, init: ty!(any);353	], {354		let mut acc = init;355		for i in arr.iter().rev() {356			acc = func.evaluate_values(context.clone(), &[acc, i?])?;357		}358		Ok(acc)359	})360}361362#[allow(non_snake_case)]363fn builtin_sort_impl(364	context: Context,365	_loc: Option<&ExprLocation>,366	args: &ArgsDesc,367) -> Result<Val> {368	parse_args!(context, "sort", args, 2, [369		0, arr: ty!(array) => Val::Arr;370		1, keyF: ty!(function) => Val::Func;371	], {372		if arr.len() <= 1 {373			return Ok(Val::Arr(arr))374		}375		Ok(Val::Arr(ArrValue::Eager(sort::sort(context, arr.evaluated()?, &keyF)?)))376	})377}378379fn builtin_format(context: Context, _loc: Option<&ExprLocation>, args: &ArgsDesc) -> Result<Val> {380	parse_args!(context, "format", args, 2, [381		0, str: ty!(string) => Val::Str;382		1, vals: ty!(any)383	], {384		std_format(str, vals)385	})386}387388fn builtin_range(context: Context, _loc: Option<&ExprLocation>, args: &ArgsDesc) -> Result<Val> {389	parse_args!(context, "range", args, 2, [390		0, from: ty!(number) => Val::Num;391		1, to: ty!(number) => Val::Num;392	], {393		if to < from {394			return Ok(Val::Arr(ArrValue::new_eager()))395		}396		let mut out = Vec::with_capacity((1+to as usize-from as usize).max(0));397		for i in from as usize..=to as usize {398			out.push(Val::Num(i as f64));399		}400		Ok(Val::Arr(out.into()))401	})402}403404fn builtin_char(context: Context, _loc: Option<&ExprLocation>, args: &ArgsDesc) -> Result<Val> {405	parse_args!(context, "char", args, 1, [406		0, n: ty!(number) => Val::Num;407	], {408		let mut out = String::new();409		out.push(std::char::from_u32(n as u32).ok_or_else(||410			InvalidUnicodeCodepointGot(n as u32)411		)?);412		Ok(Val::Str(out.into()))413	})414}415416fn builtin_encode_utf8(417	context: Context,418	_loc: Option<&ExprLocation>,419	args: &ArgsDesc,420) -> Result<Val> {421	parse_args!(context, "encodeUTF8", args, 1, [422		0, str: ty!(string) => Val::Str;423	], {424		Ok(Val::Arr((str.bytes().map(|b| Val::Num(b as f64)).collect::<Vec<Val>>()).into()))425	})426}427428fn builtin_md5(context: Context, _loc: Option<&ExprLocation>, args: &ArgsDesc) -> Result<Val> {429	parse_args!(context, "md5", args, 1, [430		0, str: ty!(string) => Val::Str;431	], {432		Ok(Val::Str(format!("{:x}", md5::compute(&str.as_bytes())).into()))433	})434}435436fn builtin_trace(context: Context, loc: Option<&ExprLocation>, args: &ArgsDesc) -> Result<Val> {437	parse_args!(context, "trace", args, 2, [438		0, str: ty!(string) => Val::Str;439		1, rest: ty!(any);440	], {441		eprint!("TRACE:");442		if let Some(loc) = loc {443			with_state(|s|{444				let locs = s.map_source_locations(&loc.0, &[loc.1]);445				eprint!(" {}:{}", loc.0.file_name().unwrap().to_str().unwrap(), locs[0].line);446			});447		}448		eprintln!(" {}", str);449		Ok(rest)450	})451}452453fn builtin_base64(context: Context, _loc: Option<&ExprLocation>, args: &ArgsDesc) -> Result<Val> {454	parse_args!(context, "base64", args, 1, [455		0, input: ty!((string | (Array<number>)));456	], {457		Ok(Val::Str(match input {458			Val::Str(s) => {459				base64::encode(s.bytes().collect::<Vec<_>>()).into()460			},461			Val::Arr(a) => {462				base64::encode(a.iter().map(|v| {463					Ok(v?.unwrap_num()? as u8)464				}).collect::<Result<Vec<_>>>()?).into()465			},466			_ => unreachable!()467		}))468	})469}470471fn builtin_join(context: Context, _loc: Option<&ExprLocation>, args: &ArgsDesc) -> Result<Val> {472	parse_args!(context, "join", args, 2, [473		0, sep: ty!((string | array));474		1, arr: ty!(array) => Val::Arr;475	], {476		Ok(match sep {477			Val::Arr(joiner_items) => {478				let mut out = Vec::new();479480				let mut first = true;481				for item in arr.iter() {482					let item = item?.clone();483					if let Val::Arr(items) = item {484						if !first {485							out.reserve(joiner_items.len());486							// TODO: extend487							for item in joiner_items.iter() {488								out.push(item?);489							}490						}491						first = false;492						out.reserve(items.len());493						// TODO: extend494						for item in items.iter() {495							out.push(item?);496						}497					} else {498						throw!(RuntimeError("in std.join all items should be arrays".into()));499					}500				}501502				Val::Arr(out.into())503			},504			Val::Str(sep) => {505				let mut out = String::new();506507				let mut first = true;508				for item in arr.iter() {509					let item = item?.clone();510					if let Val::Str(item) = item {511						if !first {512							out += &sep;513						}514						first = false;515						out += &item;516					} else {517						throw!(RuntimeError("in std.join all items should be strings".into()));518					}519				}520521				Val::Str(out.into())522			},523			_ => unreachable!()524		})525	})526}527528fn builtin_escape_string_json(529	context: Context,530	_loc: Option<&ExprLocation>,531	args: &ArgsDesc,532) -> Result<Val> {533	parse_args!(context, "escapeStringJson", args, 1, [534		0, str_: ty!(string) => Val::Str;535	], {536		Ok(Val::Str(escape_string_json(&str_).into()))537	})538}539540fn builtin_manifest_json_ex(541	context: Context,542	_loc: Option<&ExprLocation>,543	args: &ArgsDesc,544) -> Result<Val> {545	parse_args!(context, "manifestJsonEx", args, 2, [546		0, value: ty!(any);547		1, indent: ty!(string) => Val::Str;548	], {549		Ok(Val::Str(manifest_json_ex(&value, &ManifestJsonOptions {550			padding: &indent,551			mtype: ManifestType::Std,552		})?.into()))553	})554}555556fn builtin_reverse(context: Context, _loc: Option<&ExprLocation>, args: &ArgsDesc) -> Result<Val> {557	parse_args!(context, "reverse", args, 1, [558		0, value: ty!(array) => Val::Arr;559	], {560		Ok(Val::Arr(value.reversed()))561	})562}563564fn builtin_id(context: Context, _loc: Option<&ExprLocation>, args: &ArgsDesc) -> Result<Val> {565	parse_args!(context, "id", args, 1, [566		0, v: ty!(any);567	], {568		Ok(v)569	})570}571572fn builtin_str_replace(573	context: Context,574	_loc: Option<&ExprLocation>,575	args: &ArgsDesc,576) -> Result<Val> {577	parse_args!(context, "strReplace", args, 3, [578		0, str: ty!(string) => Val::Str;579		1, from: ty!(string) => Val::Str;580		2, to: ty!(string) => Val::Str;581	], {582		let mut out = String::new();583		let mut last_idx = 0;584		while let Some(idx) = (&str[last_idx..]).find(&from as &str) {585			out.push_str(&str[last_idx..last_idx+idx]);586			out.push_str(&to);587			last_idx += idx + from.len();588		}589		if last_idx == 0 {590			return Ok(Val::Str(str))591		}592		out.push_str(&str[last_idx..]);593		Ok(Val::Str(out.into()))594	})595}596597pub fn call_builtin(598	context: Context,599	loc: Option<&ExprLocation>,600	name: &str,601	args: &ArgsDesc,602) -> Result<Val> {603	BUILTINS604		.with(|builtins| builtins.get(name).copied())605		.ok_or_else(|| IntrinsicNotFound(name.into()))?(context, loc, args)606}
modifiedcrates/jrsonnet-evaluator/src/evaluate/mod.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/evaluate/mod.rs
+++ b/crates/jrsonnet-evaluator/src/evaluate/mod.rs
@@ -687,7 +687,7 @@
 				desc: &'static str,
 			) -> Result<Option<usize>> {
 				Ok(match expr {
-					Some(s) => evaluate(context.clone(), &s)?
+					Some(s) => evaluate(context.clone(), s)?
 						.try_cast_nullable_num(desc)?
 						.map(|v| v as usize),
 					None => None,
@@ -698,7 +698,7 @@
 			let end = parse_num(&context, desc.end.as_ref(), "end")?;
 			let step = parse_num(&context, desc.step.as_ref(), "step")?;
 
-			std_slice(indexable.to_indexable()?, start, end, step)?
+			std_slice(indexable.into_indexable()?, start, end, step)?
 		}
 		Import(path) => {
 			let tmp = loc
modifiedcrates/jrsonnet-evaluator/src/integrations/serde.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/integrations/serde.rs
+++ b/crates/jrsonnet-evaluator/src/integrations/serde.rs
@@ -47,7 +47,7 @@
 			Value::Number(n) => Self::Num(n.as_f64().expect("as f64")),
 			Value::String(s) => Self::Str((s as &str).into()),
 			Value::Array(a) => {
-				let mut out: Vec<Val> = Vec::with_capacity(a.len());
+				let mut out: Vec<Self> = Vec::with_capacity(a.len());
 				for v in a {
 					out.push(v.into());
 				}
@@ -58,7 +58,7 @@
 				for (k, v) in o {
 					builder.member((k as &str).into()).value(v.into());
 				}
-				Val::Obj(builder.build())
+				Self::Obj(builder.build())
 			}
 		}
 	}
modifiedcrates/jrsonnet-evaluator/src/obj.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/obj.rs
+++ b/crates/jrsonnet-evaluator/src/obj.rs
@@ -322,6 +322,11 @@
 		ObjValue::new(self.super_obj, Gc::new(self.map), Gc::new(self.assertions))
 	}
 }
+impl Default for ObjValueBuilder {
+	fn default() -> Self {
+		Self::with_capacity(0)
+	}
+}
 
 #[must_use = "value not added unless binding() was called"]
 pub struct ObjMemberBuilder<'v> {
@@ -332,8 +337,9 @@
 	location: Option<ExprLocation>,
 }
 
+#[allow(clippy::missing_const_for_fn)]
 impl<'v> ObjMemberBuilder<'v> {
-	pub fn with_add(mut self, add: bool) -> Self {
+	pub const fn with_add(mut self, add: bool) -> Self {
 		self.add = add;
 		self
 	}
modifiedcrates/jrsonnet-evaluator/src/val.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/val.rs
+++ b/crates/jrsonnet-evaluator/src/val.rs
@@ -571,7 +571,7 @@
 			.try_cast_str("to json")
 		})
 	}
-	pub fn to_indexable(self) -> Result<IndexableVal> {
+	pub fn into_indexable(self) -> Result<IndexableVal> {
 		Ok(match self {
 			Val::Str(s) => IndexableVal::Str(s),
 			Val::Arr(arr) => IndexableVal::Arr(arr),