git.delta.rocks / jrsonnet / refs/commits / 3fc6c25f159a

difftreelog

style fix clippy warnings

Yaroslav Bolyukin2021-01-24parent: #2634495.patch.diff
in: master

9 files changed

modifiedcrates/jrsonnet-evaluator/src/builtin/manifest.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/builtin/manifest.rs
+++ b/crates/jrsonnet-evaluator/src/builtin/manifest.rs
@@ -42,7 +42,7 @@
 			}
 		}
 		Val::Null => buf.push_str("null"),
-		Val::Str(s) => buf.push_str(&escape_string_json(&s)),
+		Val::Str(s) => buf.push_str(&escape_string_json(s)),
 		Val::Num(n) => write!(buf, "{}", n).unwrap(),
 		Val::Arr(items) => {
 			buf.push('[');
modifiedcrates/jrsonnet-evaluator/src/builtin/mod.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/builtin/mod.rs
+++ b/crates/jrsonnet-evaluator/src/builtin/mod.rs
@@ -445,7 +445,7 @@
 			},
 			Val::Arr(a) => {
 				base64::encode(a.iter().map(|v| {
-					Ok(v?.clone().unwrap_num()? as u8)
+					Ok(v?.unwrap_num()? as u8)
 				}).collect::<Result<Vec<_>>>()?).into()
 			},
 			_ => unreachable!()
@@ -589,7 +589,7 @@
 	name: &str,
 	args: &ArgsDesc,
 ) -> Result<Val> {
-	if let Some(f) = BUILTINS.with(|builtins| builtins.get(name).map(|f| *f)) {
+	if let Some(f) = BUILTINS.with(|builtins| builtins.get(name).copied()) {
 		return Ok(f(context, loc, args)?);
 	}
 	throw!(IntrinsicNotFound(name.into()))
modifiedcrates/jrsonnet-evaluator/src/evaluate.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/evaluate.rs
+++ b/crates/jrsonnet-evaluator/src/evaluate.rs
@@ -473,7 +473,6 @@
 					}
 					v.get(n as usize)?
 						.ok_or_else(|| ArrayBoundsError(n as usize, v.len()))?
-						.clone()
 				}
 				(Val::Arr(_), Val::Str(n)) => throw!(AttemptedIndexAnArrayWithString(n)),
 				(Val::Arr(_), n) => throw!(ValueIndexMustBeTypeGot(
modifiedcrates/jrsonnet-evaluator/src/native.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/native.rs
+++ b/crates/jrsonnet-evaluator/src/native.rs
@@ -1,3 +1,5 @@
+#![allow(clippy::type_complexity)]
+
 use crate::{error::Result, Val};
 use jrsonnet_parser::ParamsDesc;
 use std::fmt::Debug;
modifiedcrates/jrsonnet-evaluator/src/obj.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/obj.rs
+++ b/crates/jrsonnet-evaluator/src/obj.rs
@@ -34,7 +34,7 @@
 		}
 		let mut debug = f.debug_struct("ObjValue");
 		for (name, member) in self.0.this_entries.iter() {
-			debug.field(&name, member);
+			debug.field(name, member);
 		}
 		#[cfg(feature = "unstable")]
 		{
@@ -140,7 +140,7 @@
 			.evaluate()?)
 	}
 
-	pub fn ptr_eq(a: &ObjValue, b: &ObjValue) -> bool {
+	pub fn ptr_eq(a: &Self, b: &Self) -> bool {
 		Rc::ptr_eq(&a.0, &b.0)
 	}
 }
modifiedcrates/jrsonnet-evaluator/src/typed.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/typed.rs
+++ b/crates/jrsonnet-evaluator/src/typed.rs
@@ -29,7 +29,7 @@
 pub struct TypeLocError(Box<TypeError>, ValuePathStack);
 impl From<TypeError> for TypeLocError {
 	fn from(e: TypeError) -> Self {
-		TypeLocError(Box::new(e), ValuePathStack(Vec::new()))
+		Self(Box::new(e), ValuePathStack(Vec::new()))
 	}
 }
 impl From<TypeLocError> for LocError {
@@ -61,7 +61,7 @@
 			write!(out, "{}", err)?;
 
 			for (i, line) in out.lines().enumerate() {
-				if line.trim().len() == 0 {
+				if line.trim().is_empty() {
 					continue;
 				}
 				if i != 0 {
@@ -118,8 +118,8 @@
 impl Display for ValuePathItem {
 	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
 		match self {
-			ValuePathItem::Field(name) => write!(f, ".{}", name)?,
-			ValuePathItem::Index(idx) => write!(f, "[{}]", idx)?,
+			Self::Field(name) => write!(f, ".{}", name)?,
+			Self::Index(idx) => write!(f, "[{}]", idx)?,
 		}
 		Ok(())
 	}
@@ -140,25 +140,25 @@
 impl CheckType for ComplexValType {
 	fn check(&self, value: &Val) -> Result<()> {
 		match self {
-			ComplexValType::Any => Ok(()),
-			ComplexValType::Simple(s) => s.check(value),
-			ComplexValType::Char => match value {
+			Self::Any => Ok(()),
+			Self::Simple(s) => s.check(value),
+			Self::Char => match value {
 				Val::Str(s) if s.len() == 1 || s.chars().count() == 1 => Ok(()),
 				v => Err(TypeError::ExpectedGot(self.clone(), v.value_type()).into()),
 			},
-			ComplexValType::BoundedNumber(from, to) => {
+			Self::BoundedNumber(from, to) => {
 				if let Val::Num(n) = value {
 					if from.map(|from| from > *n).unwrap_or(false)
 						|| to.map(|to| to <= *n).unwrap_or(false)
 					{
-						return Err(TypeError::BoundsFailed(*n, from.clone(), to.clone()).into());
+						return Err(TypeError::BoundsFailed(*n, *from, *to).into());
 					}
 					Ok(())
 				} else {
 					Err(TypeError::ExpectedGot(self.clone(), value.value_type()).into())
 				}
 			}
-			ComplexValType::Array(elem_type) => match value {
+			Self::Array(elem_type) => match value {
 				Val::Arr(a) => {
 					for (i, item) in a.iter().enumerate() {
 						push_type(
@@ -170,9 +170,9 @@
 					}
 					Ok(())
 				}
-				v => return Err(TypeError::ExpectedGot(self.clone(), v.value_type()).into()),
+				v => Err(TypeError::ExpectedGot(self.clone(), v.value_type()).into()),
 			},
-			ComplexValType::ArrayRef(elem_type) => match value {
+			Self::ArrayRef(elem_type) => match value {
 				Val::Arr(a) => {
 					for (i, item) in a.iter().enumerate() {
 						push_type(
@@ -184,9 +184,9 @@
 					}
 					Ok(())
 				}
-				v => return Err(TypeError::ExpectedGot(self.clone(), v.value_type()).into()),
+				v => Err(TypeError::ExpectedGot(self.clone(), v.value_type()).into()),
 			},
-			ComplexValType::ObjectRef(elems) => match value {
+			Self::ObjectRef(elems) => match value {
 				Val::Obj(obj) => {
 					for (k, v) in elems.iter() {
 						if let Some(got_v) = obj.get((*k).into())? {
@@ -202,11 +202,11 @@
 							);
 						}
 					}
-					return Ok(());
+					Ok(())
 				}
-				v => return Err(TypeError::ExpectedGot(self.clone(), v.value_type()).into()),
+				v => Err(TypeError::ExpectedGot(self.clone(), v.value_type()).into()),
 			},
-			ComplexValType::Union(types) => {
+			Self::Union(types) => {
 				let mut errors = Vec::new();
 				for ty in types.iter() {
 					match ty.check(value) {
@@ -219,9 +219,9 @@
 						},
 					}
 				}
-				return Err(TypeError::UnionFailed(self.clone(), TypeLocErrorList(errors)).into());
+				Err(TypeError::UnionFailed(self.clone(), TypeLocErrorList(errors)).into())
 			}
-			ComplexValType::UnionRef(types) => {
+			Self::UnionRef(types) => {
 				let mut errors = Vec::new();
 				for ty in types.iter() {
 					match ty.check(value) {
@@ -234,15 +234,15 @@
 						},
 					}
 				}
-				return Err(TypeError::UnionFailed(self.clone(), TypeLocErrorList(errors)).into());
+				Err(TypeError::UnionFailed(self.clone(), TypeLocErrorList(errors)).into())
 			}
-			ComplexValType::Sum(types) => {
+			Self::Sum(types) => {
 				for ty in types.iter() {
 					ty.check(value)?
 				}
 				Ok(())
 			}
-			ComplexValType::SumRef(types) => {
+			Self::SumRef(types) => {
 				for ty in types.iter() {
 					ty.check(value)?
 				}
modifiedcrates/jrsonnet-evaluator/src/val.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/val.rs
+++ b/crates/jrsonnet-evaluator/src/val.rs
@@ -176,14 +176,14 @@
 pub enum ArrValue {
 	Lazy(Rc<Vec<LazyVal>>),
 	Eager(Rc<Vec<Val>>),
-	Extended(Box<(ArrValue, ArrValue)>),
+	Extended(Box<(Self, Self)>),
 }
 impl ArrValue {
 	pub fn len(&self) -> usize {
 		match self {
-			ArrValue::Lazy(l) => l.len(),
-			ArrValue::Eager(e) => e.len(),
-			ArrValue::Extended(v) => v.0.len() + v.1.len(),
+			Self::Lazy(l) => l.len(),
+			Self::Eager(e) => e.len(),
+			Self::Extended(v) => v.0.len() + v.1.len(),
 		}
 	}
 
@@ -193,15 +193,15 @@
 
 	pub fn get(&self, index: usize) -> Result<Option<Val>> {
 		match self {
-			ArrValue::Lazy(vec) => {
+			Self::Lazy(vec) => {
 				if let Some(v) = vec.get(index) {
 					Ok(Some(v.evaluate()?))
 				} else {
 					Ok(None)
 				}
 			}
-			ArrValue::Eager(vec) => Ok(vec.get(index).cloned()),
-			ArrValue::Extended(v) => {
+			Self::Eager(vec) => Ok(vec.get(index).cloned()),
+			Self::Extended(v) => {
 				let a_len = v.0.len();
 				if a_len > index {
 					v.0.get(index)
@@ -214,12 +214,9 @@
 
 	pub fn get_lazy(&self, index: usize) -> Option<LazyVal> {
 		match self {
-			ArrValue::Lazy(vec) => vec.get(index).cloned(),
-			ArrValue::Eager(vec) => vec
-				.get(index)
-				.cloned()
-				.map(|val| LazyVal::new_resolved(val)),
-			ArrValue::Extended(v) => {
+			Self::Lazy(vec) => vec.get(index).cloned(),
+			Self::Eager(vec) => vec.get(index).cloned().map(LazyVal::new_resolved),
+			Self::Extended(v) => {
 				let a_len = v.0.len();
 				if a_len > index {
 					v.0.get_lazy(index)
@@ -232,15 +229,15 @@
 
 	pub fn evaluated(&self) -> Result<Rc<Vec<Val>>> {
 		Ok(match self {
-			ArrValue::Lazy(vec) => {
+			Self::Lazy(vec) => {
 				let mut out = Vec::with_capacity(vec.len());
 				for item in vec.iter() {
 					out.push(item.evaluate()?);
 				}
 				Rc::new(out)
 			}
-			ArrValue::Eager(vec) => vec.clone(),
-			ArrValue::Extended(v) => {
+			Self::Eager(vec) => vec.clone(),
+			Self::Extended(_v) => {
 				let mut out = Vec::with_capacity(self.len());
 				for item in self.iter() {
 					out.push(item?);
@@ -252,40 +249,40 @@
 
 	pub fn iter(&self) -> impl DoubleEndedIterator<Item = Result<Val>> + '_ {
 		(0..self.len()).map(move |idx| match self {
-			ArrValue::Lazy(l) => l[idx].evaluate(),
-			ArrValue::Eager(e) => Ok(e[idx].clone()),
-			ArrValue::Extended(_) => self.get(idx).map(|e| e.unwrap()),
+			Self::Lazy(l) => l[idx].evaluate(),
+			Self::Eager(e) => Ok(e[idx].clone()),
+			Self::Extended(_) => self.get(idx).map(|e| e.unwrap()),
 		})
 	}
 
 	pub fn iter_lazy(&self) -> impl DoubleEndedIterator<Item = LazyVal> + '_ {
 		(0..self.len()).map(move |idx| match self {
-			ArrValue::Lazy(l) => l[idx].clone(),
-			ArrValue::Eager(e) => LazyVal::new_resolved(e[idx].clone()),
-			ArrValue::Extended(_) => self.get_lazy(idx).unwrap(),
+			Self::Lazy(l) => l[idx].clone(),
+			Self::Eager(e) => LazyVal::new_resolved(e[idx].clone()),
+			Self::Extended(_) => self.get_lazy(idx).unwrap(),
 		})
 	}
 
 	pub fn reversed(self) -> Self {
 		match self {
-			ArrValue::Lazy(vec) => {
+			Self::Lazy(vec) => {
 				let mut out = (&vec as &Vec<_>).clone();
 				out.reverse();
 				Self::Lazy(Rc::new(out))
 			}
-			ArrValue::Eager(vec) => {
+			Self::Eager(vec) => {
 				let mut out = (&vec as &Vec<_>).clone();
 				out.reverse();
 				Self::Eager(Rc::new(out))
 			}
-			ArrValue::Extended(b) => ArrValue::Extended(Box::new((b.1.reversed(), b.0.reversed()))),
+			Self::Extended(b) => Self::Extended(Box::new((b.1.reversed(), b.0.reversed()))),
 		}
 	}
 
-	pub fn ptr_eq(a: &ArrValue, b: &ArrValue) -> bool {
+	pub fn ptr_eq(a: &Self, b: &Self) -> bool {
 		match (a, b) {
-			(ArrValue::Lazy(a), ArrValue::Lazy(b)) => Rc::ptr_eq(a, b),
-			(ArrValue::Eager(a), ArrValue::Eager(b)) => Rc::ptr_eq(a, b),
+			(Self::Lazy(a), Self::Lazy(b)) => Rc::ptr_eq(a, b),
+			(Self::Eager(a), Self::Eager(b)) => Rc::ptr_eq(a, b),
 			_ => false,
 		}
 	}
@@ -359,7 +356,7 @@
 		self.assert_type(context, ValType::Num)?;
 		self.unwrap_num()
 	}
-	pub fn value_type(&self) -> ValType {
+	pub const fn value_type(&self) -> ValType {
 		match self {
 			Self::Str(..) => ValType::Str,
 			Self::Num(..) => ValType::Num,
@@ -378,7 +375,7 @@
 			Self::Null => "null".into(),
 			Self::Str(s) => s.clone(),
 			v => manifest_json_ex(
-				&v,
+				v,
 				&ManifestJsonOptions {
 					padding: "",
 					mtype: ManifestType::ToString,
@@ -556,7 +553,7 @@
 		(Val::Obj(_), Val::Obj(_)) => throw!(RuntimeError(
 			"primitiveEquals operates on primitive types, got object".into(),
 		)),
-		(a, b) if is_function_like(&a) && is_function_like(&b) => {
+		(a, b) if is_function_like(a) && is_function_like(b) => {
 			throw!(RuntimeError("cannot test equality of functions".into()))
 		}
 		(_, _) => false,
@@ -598,6 +595,6 @@
 			}
 			Ok(true)
 		}
-		(a, b) => Ok(primitive_equals(&a, &b)?),
+		(a, b) => Ok(primitive_equals(a, b)?),
 	}
 }
modifiedcrates/jrsonnet-interner/src/lib.rsdiffbeforeafterboth
--- a/crates/jrsonnet-interner/src/lib.rs
+++ b/crates/jrsonnet-interner/src/lib.rs
@@ -68,7 +68,7 @@
 		IStr(STR_POOL.with(|pool| {
 			let mut pool = pool.borrow_mut();
 			if let Some((k, _)) = pool.get_key_value(str) {
-				return k.clone();
+				k.clone()
 			} else {
 				let rc: Rc<str> = str.into();
 				pool.insert(rc.clone(), ());
modifiedcrates/jrsonnet-types/src/lib.rsdiffbeforeafterboth
before · crates/jrsonnet-types/src/lib.rs
1use std::fmt::Display;23#[macro_export]4macro_rules! ty {5	((Array<number>)) => {{6		$crate::ComplexValType::ArrayRef(&$crate::ComplexValType::Simple($crate::ValType::Num))7	}};8	(array) => {9		$crate::ComplexValType::Simple($crate::ValType::Arr)10	};11	(boolean) => {12		$crate::ComplexValType::Simple($crate::ValType::Bool)13	};14	(null) => {15		$crate::ComplexValType::Simple($crate::ValType::Null)16	};17	(string) => {18		$crate::ComplexValType::Simple($crate::ValType::Str)19	};20	(char) => {21		$crate::ComplexValType::Char22	};23	(number) => {24		$crate::ComplexValType::Simple($crate::ValType::Num)25	};26	(BoundedNumber<($min:expr), ($max:expr)>) => {{27		$crate::ComplexValType::BoundedNumber($min, $max)28	}};29	(object) => {30		$crate::ComplexValType::Simple($crate::ValType::Obj)31	};32	(any) => {33		$crate::ComplexValType::Any34	};35	(function) => {36		$crate::ComplexValType::Simple($crate::ValType::Func)37	};38	(($($a:tt) |+)) => {{39		static CONTENTS: &'static [$crate::ComplexValType] = &[40			$(ty!($a)),+41		];42		$crate::ComplexValType::UnionRef(CONTENTS)43	}};44	(($($a:tt) &+)) => {{45		static CONTENTS: &'static [$crate::ComplexValType] = &[46			$(ty!($a)),+47		];48		$crate::ComplexValType::SumRef(CONTENTS)49	}};50}5152#[test]53fn test() {54	assert_eq!(55		ty!((Array<number>)),56		ComplexValType::ArrayRef(&ComplexValType::Simple(ValType::Num))57	);58	assert_eq!(ty!(array), ComplexValType::Simple(ValType::Arr));59	assert_eq!(ty!(any), ComplexValType::Any);60	assert_eq!(61		ty!((string | number)),62		ComplexValType::UnionRef(&[63			ComplexValType::Simple(ValType::Str),64			ComplexValType::Simple(ValType::Num)65		])66	);67	assert_eq!(68		format!("{}", ty!(((string & number) | (object & null)))),69		"string & number | object & null"70	);71	assert_eq!(format!("{}", ty!((string | array))), "string | array");72	assert_eq!(73		format!("{}", ty!(((string & number) | array))),74		"string & number | array"75	);76}7778#[derive(Debug, Clone, Copy, PartialEq, Eq)]79pub enum ValType {80	Bool,81	Null,82	Str,83	Num,84	Arr,85	Obj,86	Func,87}8889impl ValType {90	pub const fn name(&self) -> &'static str {91		use ValType::*;92		match self {93			Bool => "boolean",94			Null => "null",95			Str => "string",96			Num => "number",97			Arr => "array",98			Obj => "object",99			Func => "function",100		}101	}102}103104impl Display for ValType {105	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {106		write!(f, "{}", self.name())107	}108}109110#[derive(Debug, Clone, PartialEq)]111pub enum ComplexValType {112	Any,113	Char,114	Simple(ValType),115	BoundedNumber(Option<f64>, Option<f64>),116	Array(Box<ComplexValType>),117	ArrayRef(&'static ComplexValType),118	ObjectRef(&'static [(&'static str, ComplexValType)]),119	Union(Vec<ComplexValType>),120	UnionRef(&'static [ComplexValType]),121	Sum(Vec<ComplexValType>),122	SumRef(&'static [ComplexValType]),123}124impl From<ValType> for ComplexValType {125	fn from(s: ValType) -> Self {126		Self::Simple(s)127	}128}129130fn write_union(131	f: &mut std::fmt::Formatter<'_>,132	is_union: bool,133	union: &[ComplexValType],134) -> std::fmt::Result {135	for (i, v) in union.iter().enumerate() {136		let should_add_braces = match v {137			ComplexValType::UnionRef(_) | ComplexValType::Union(_) if !is_union => true,138			_ => false,139		};140		if i != 0 {141			write!(f, " {} ", if is_union { '|' } else { '&' })?;142		}143		if should_add_braces {144			write!(f, "(")?;145		}146		write!(f, "{}", v)?;147		if should_add_braces {148			write!(f, ")")?;149		}150	}151	Ok(())152}153154fn print_array(a: &ComplexValType, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {155	if *a == ComplexValType::Any {156		write!(f, "array")?157	} else {158		write!(f, "Array<{}>", a)?159	}160	Ok(())161}162163impl Display for ComplexValType {164	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {165		match self {166			ComplexValType::Any => write!(f, "any")?,167			ComplexValType::Simple(s) => write!(f, "{}", s)?,168			ComplexValType::Char => write!(f, "char")?,169			ComplexValType::BoundedNumber(a, b) => write!(170				f,171				"BoundedNumber<{}, {}>",172				a.map(|e| e.to_string()).unwrap_or_else(|| "".into()),173				b.map(|e| e.to_string()).unwrap_or_else(|| "".into())174			)?,175			ComplexValType::ArrayRef(a) => print_array(a, f)?,176			ComplexValType::Array(a) => print_array(a, f)?,177			ComplexValType::ObjectRef(fields) => {178				write!(f, "{{")?;179				for (i, (k, v)) in fields.iter().enumerate() {180					if i != 0 {181						write!(f, ", ")?;182					}183					write!(f, "{}: {}", k, v)?;184				}185				write!(f, "}}")?;186			}187			ComplexValType::Union(v) => write_union(f, true, v)?,188			ComplexValType::UnionRef(v) => write_union(f, true, v)?,189			ComplexValType::Sum(v) => write_union(f, false, v)?,190			ComplexValType::SumRef(v) => write_union(f, false, v)?,191		};192		Ok(())193	}194}195196peg::parser! {197pub grammar parser() for str {198	rule number() -> f64199		= n:$(['0'..='9']+) { n.parse().unwrap() }200201	rule any_ty() -> ComplexValType = "any" { ComplexValType::Any }202	rule char_ty() -> ComplexValType = "character" { ComplexValType::Char }203	rule bool_ty() -> ComplexValType = "boolean" { ComplexValType::Simple(ValType::Bool) }204	rule null_ty() -> ComplexValType = "null" { ComplexValType::Simple(ValType::Null) }205	rule str_ty() -> ComplexValType = "string" { ComplexValType::Simple(ValType::Str) }206	rule num_ty() -> ComplexValType = "number" { ComplexValType::Simple(ValType::Num) }207	rule simple_array_ty() -> ComplexValType = "array" { ComplexValType::Simple(ValType::Arr) }208	rule simple_object_ty() -> ComplexValType = "object" { ComplexValType::Simple(ValType::Obj) }209	rule simple_function_ty() -> ComplexValType = "function" { ComplexValType::Simple(ValType::Func) }210211	rule array_ty() -> ComplexValType212		= "Array<" t:ty() ">" { ComplexValType::Array(Box::new(t)) }213214	rule bounded_number_ty() -> ComplexValType215		= "BoundedNumber<" a:number() ", " b:number() ">" { ComplexValType::BoundedNumber(Some(a), Some(b)) }216217	rule ty_basic() -> ComplexValType218		= any_ty()219		/ char_ty()220		/ bool_ty()221		/ null_ty()222		/ str_ty()223		/ num_ty()224		/ simple_array_ty()225		/ simple_object_ty()226		/ simple_function_ty()227		/ array_ty()228		/ bounded_number_ty()229230	pub rule ty() -> ComplexValType231		= precedence! {232			a:(@) " | " b:@ {233				match a {234					ComplexValType::Union(mut a) => {235						a.push(b);236						ComplexValType::Union(a)237					}238					_ => ComplexValType::Union(vec![a, b]),239				}240			}241			--242			a:(@) " & " b:@ {243				match a {244					ComplexValType::Sum(mut a) => {245						a.push(b);246						ComplexValType::Sum(a)247					}248					_ => ComplexValType::Sum(vec![a, b]),249				}250			}251			--252			"(" t:ty() ")" { t }253			t:ty_basic() { t }254		}255}256}257258#[cfg(test)]259pub mod tests {260	use super::parser;261262	#[test]263	fn precedence() {264		assert_eq!(265			parser::ty("(any & any) | (any | any) & any")266				.unwrap()267				.to_string(),268			"any & any | (any | any) & any"269		);270	}271272	#[test]273	fn array() {274		assert_eq!(parser::ty("Array<any>").unwrap().to_string(), "array");275		assert_eq!(276			parser::ty("Array<number>").unwrap().to_string(),277			"Array<number>"278		);279	}280	#[test]281	fn bounded_number() {282		assert_eq!(283			parser::ty("BoundedNumber<1, 2>").unwrap().to_string(),284			"BoundedNumber<1, 2>"285		);286	}287}
after · crates/jrsonnet-types/src/lib.rs
1use std::fmt::Display;23#[macro_export]4macro_rules! ty {5	((Array<number>)) => {{6		$crate::ComplexValType::ArrayRef(&$crate::ComplexValType::Simple($crate::ValType::Num))7	}};8	(array) => {9		$crate::ComplexValType::Simple($crate::ValType::Arr)10	};11	(boolean) => {12		$crate::ComplexValType::Simple($crate::ValType::Bool)13	};14	(null) => {15		$crate::ComplexValType::Simple($crate::ValType::Null)16	};17	(string) => {18		$crate::ComplexValType::Simple($crate::ValType::Str)19	};20	(char) => {21		$crate::ComplexValType::Char22	};23	(number) => {24		$crate::ComplexValType::Simple($crate::ValType::Num)25	};26	(BoundedNumber<($min:expr), ($max:expr)>) => {{27		$crate::ComplexValType::BoundedNumber($min, $max)28	}};29	(object) => {30		$crate::ComplexValType::Simple($crate::ValType::Obj)31	};32	(any) => {33		$crate::ComplexValType::Any34	};35	(function) => {36		$crate::ComplexValType::Simple($crate::ValType::Func)37	};38	(($($a:tt) |+)) => {{39		static CONTENTS: &'static [$crate::ComplexValType] = &[40			$(ty!($a)),+41		];42		$crate::ComplexValType::UnionRef(CONTENTS)43	}};44	(($($a:tt) &+)) => {{45		static CONTENTS: &'static [$crate::ComplexValType] = &[46			$(ty!($a)),+47		];48		$crate::ComplexValType::SumRef(CONTENTS)49	}};50}5152#[test]53fn test() {54	assert_eq!(55		ty!((Array<number>)),56		ComplexValType::ArrayRef(&ComplexValType::Simple(ValType::Num))57	);58	assert_eq!(ty!(array), ComplexValType::Simple(ValType::Arr));59	assert_eq!(ty!(any), ComplexValType::Any);60	assert_eq!(61		ty!((string | number)),62		ComplexValType::UnionRef(&[63			ComplexValType::Simple(ValType::Str),64			ComplexValType::Simple(ValType::Num)65		])66	);67	assert_eq!(68		format!("{}", ty!(((string & number) | (object & null)))),69		"string & number | object & null"70	);71	assert_eq!(format!("{}", ty!((string | array))), "string | array");72	assert_eq!(73		format!("{}", ty!(((string & number) | array))),74		"string & number | array"75	);76}7778#[derive(Debug, Clone, Copy, PartialEq, Eq)]79pub enum ValType {80	Bool,81	Null,82	Str,83	Num,84	Arr,85	Obj,86	Func,87}8889impl ValType {90	pub const fn name(&self) -> &'static str {91		use ValType::*;92		match self {93			Bool => "boolean",94			Null => "null",95			Str => "string",96			Num => "number",97			Arr => "array",98			Obj => "object",99			Func => "function",100		}101	}102}103104impl Display for ValType {105	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {106		write!(f, "{}", self.name())107	}108}109110#[derive(Debug, Clone, PartialEq)]111pub enum ComplexValType {112	Any,113	Char,114	Simple(ValType),115	BoundedNumber(Option<f64>, Option<f64>),116	Array(Box<ComplexValType>),117	ArrayRef(&'static ComplexValType),118	ObjectRef(&'static [(&'static str, ComplexValType)]),119	Union(Vec<ComplexValType>),120	UnionRef(&'static [ComplexValType]),121	Sum(Vec<ComplexValType>),122	SumRef(&'static [ComplexValType]),123}124impl From<ValType> for ComplexValType {125	fn from(s: ValType) -> Self {126		Self::Simple(s)127	}128}129130fn write_union(131	f: &mut std::fmt::Formatter<'_>,132	is_union: bool,133	union: &[ComplexValType],134) -> std::fmt::Result {135	for (i, v) in union.iter().enumerate() {136		let should_add_braces =137			matches!(v, ComplexValType::UnionRef(_) | ComplexValType::Union(_) if !is_union);138		if i != 0 {139			write!(f, " {} ", if is_union { '|' } else { '&' })?;140		}141		if should_add_braces {142			write!(f, "(")?;143		}144		write!(f, "{}", v)?;145		if should_add_braces {146			write!(f, ")")?;147		}148	}149	Ok(())150}151152fn print_array(a: &ComplexValType, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {153	if *a == ComplexValType::Any {154		write!(f, "array")?155	} else {156		write!(f, "Array<{}>", a)?157	}158	Ok(())159}160161impl Display for ComplexValType {162	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {163		match self {164			ComplexValType::Any => write!(f, "any")?,165			ComplexValType::Simple(s) => write!(f, "{}", s)?,166			ComplexValType::Char => write!(f, "char")?,167			ComplexValType::BoundedNumber(a, b) => write!(168				f,169				"BoundedNumber<{}, {}>",170				a.map(|e| e.to_string()).unwrap_or_else(|| "".into()),171				b.map(|e| e.to_string()).unwrap_or_else(|| "".into())172			)?,173			ComplexValType::ArrayRef(a) => print_array(a, f)?,174			ComplexValType::Array(a) => print_array(a, f)?,175			ComplexValType::ObjectRef(fields) => {176				write!(f, "{{")?;177				for (i, (k, v)) in fields.iter().enumerate() {178					if i != 0 {179						write!(f, ", ")?;180					}181					write!(f, "{}: {}", k, v)?;182				}183				write!(f, "}}")?;184			}185			ComplexValType::Union(v) => write_union(f, true, v)?,186			ComplexValType::UnionRef(v) => write_union(f, true, v)?,187			ComplexValType::Sum(v) => write_union(f, false, v)?,188			ComplexValType::SumRef(v) => write_union(f, false, v)?,189		};190		Ok(())191	}192}193194peg::parser! {195pub grammar parser() for str {196	rule number() -> f64197		= n:$(['0'..='9']+) { n.parse().unwrap() }198199	rule any_ty() -> ComplexValType = "any" { ComplexValType::Any }200	rule char_ty() -> ComplexValType = "character" { ComplexValType::Char }201	rule bool_ty() -> ComplexValType = "boolean" { ComplexValType::Simple(ValType::Bool) }202	rule null_ty() -> ComplexValType = "null" { ComplexValType::Simple(ValType::Null) }203	rule str_ty() -> ComplexValType = "string" { ComplexValType::Simple(ValType::Str) }204	rule num_ty() -> ComplexValType = "number" { ComplexValType::Simple(ValType::Num) }205	rule simple_array_ty() -> ComplexValType = "array" { ComplexValType::Simple(ValType::Arr) }206	rule simple_object_ty() -> ComplexValType = "object" { ComplexValType::Simple(ValType::Obj) }207	rule simple_function_ty() -> ComplexValType = "function" { ComplexValType::Simple(ValType::Func) }208209	rule array_ty() -> ComplexValType210		= "Array<" t:ty() ">" { ComplexValType::Array(Box::new(t)) }211212	rule bounded_number_ty() -> ComplexValType213		= "BoundedNumber<" a:number() ", " b:number() ">" { ComplexValType::BoundedNumber(Some(a), Some(b)) }214215	rule ty_basic() -> ComplexValType216		= any_ty()217		/ char_ty()218		/ bool_ty()219		/ null_ty()220		/ str_ty()221		/ num_ty()222		/ simple_array_ty()223		/ simple_object_ty()224		/ simple_function_ty()225		/ array_ty()226		/ bounded_number_ty()227228	pub rule ty() -> ComplexValType229		= precedence! {230			a:(@) " | " b:@ {231				match a {232					ComplexValType::Union(mut a) => {233						a.push(b);234						ComplexValType::Union(a)235					}236					_ => ComplexValType::Union(vec![a, b]),237				}238			}239			--240			a:(@) " & " b:@ {241				match a {242					ComplexValType::Sum(mut a) => {243						a.push(b);244						ComplexValType::Sum(a)245					}246					_ => ComplexValType::Sum(vec![a, b]),247				}248			}249			--250			"(" t:ty() ")" { t }251			t:ty_basic() { t }252		}253}254}255256#[cfg(test)]257pub mod tests {258	use super::parser;259260	#[test]261	fn precedence() {262		assert_eq!(263			parser::ty("(any & any) | (any | any) & any")264				.unwrap()265				.to_string(),266			"any & any | (any | any) & any"267		);268	}269270	#[test]271	fn array() {272		assert_eq!(parser::ty("Array<any>").unwrap().to_string(), "array");273		assert_eq!(274			parser::ty("Array<number>").unwrap().to_string(),275			"Array<number>"276		);277	}278	#[test]279	fn bounded_number() {280		assert_eq!(281			parser::ty("BoundedNumber<1, 2>").unwrap().to_string(),282			"BoundedNumber<1, 2>"283		);284	}285}