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

difftreelog

feat describe jrsonnet type system

Yaroslav Bolyukin2021-01-06parent: #5ffc4ed.patch.diff
in: master

2 files changed

addedcrates/jrsonnet-types/Cargo.tomldiffbeforeafterboth
--- /dev/null
+++ b/crates/jrsonnet-types/Cargo.toml
@@ -0,0 +1,7 @@
+[package]
+name = "jrsonnet-types"
+version = "0.3.2"
+authors = ["Yaroslav Bolyukin <iam@lach.pw>"]
+edition = "2018"
+
+[dependencies]
addedcrates/jrsonnet-types/src/lib.rsdiffbeforeafterboth
after · crates/jrsonnet-types/src/lib.rs
1use std::fmt::Display;23#[macro_export]4macro_rules! ty {5	([$inner:tt]) => {{6		static VAL: &'static ComplexValType = &ty!($inner);7		match VAL {8			ComplexValType::Any => ComplexValType::Simple(ValType::Arr),9			_ => ComplexValType::ArrayRef(&VAL),10		}11	}};12	(bool) => {13		ComplexValType::Simple(ValType::Bool)14	};15	(null) => {16		ComplexValType::Simple(ValType::Null)17	};18	(str) => {19		ComplexValType::Simple(ValType::Str)20	};21	(char) => {22		ComplexValType::Char23	};24	(num) => {25		ComplexValType::Simple(ValType::Num)26	};27	(number(($min:expr)..($max:expr))) => {{28		ComplexValType::BoundedNumber($min, $max)29	}};30	(obj) => {31		ComplexValType::Simple(ValType::Obj)32	};33	(any) => {34		ComplexValType::Any35	};36	(fn.any) => {37		ComplexValType::Simple(ValType::Func)38	};39	(($($a:tt) |+)) => {{40		static CONTENTS: &'static [ComplexValType] = &[41			$(ty!($a)),+42		];43		ComplexValType::UnionRef(CONTENTS)44	}};45	(($($a:tt) &+)) => {{46		static CONTENTS: &'static [ComplexValType] = &[47			$(ty!($a)),+48		];49		ComplexValType::SumRef(CONTENTS)50	}};51}5253#[test]54fn test() {55	assert_eq!(56		ty!([num]),57		ComplexValType::ArrayRef(&ComplexValType::Simple(ValType::Num))58	);59	assert_eq!(ty!([any]), ComplexValType::Simple(ValType::Arr));60	assert_eq!(ty!(any), ComplexValType::Any);61	assert_eq!(62		ty!((str | num)),63		ComplexValType::UnionRef(&[64			ComplexValType::Simple(ValType::Str),65			ComplexValType::Simple(ValType::Num)66		])67	);68	assert_eq!(69		format!("{}", ty!(((str & num) | (obj & null)))),70		"((str & num) | (obj & null))"71	);72	assert_eq!(format!("{}", ty!((str | [any]))), "(str | [any])");73}7475#[derive(Debug, Clone, Copy, PartialEq, Eq)]76pub enum ValType {77	Bool,78	Null,79	Str,80	Num,81	Arr,82	Obj,83	Func,84}8586impl ValType {87	pub const fn name(&self) -> &'static str {88		use ValType::*;89		match self {90			Bool => "bool",91			Null => "null",92			Str => "str",93			Num => "num",94			Arr => "[any]",95			Obj => "obj",96			Func => "fn.any",97		}98	}99}100101impl Display for ValType {102	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {103		write!(f, "{}", self.name())104	}105}106107#[derive(Debug, Clone, PartialEq)]108pub enum ComplexValType {109	Any,110	Char,111	Simple(ValType),112	BoundedNumber(Option<f64>, Option<f64>),113	ArrayRef(&'static ComplexValType),114	ObjectRef(&'static [(&'static str, ComplexValType)]),115	UnionRef(&'static [ComplexValType]),116	SumRef(&'static [ComplexValType]),117}118impl From<ValType> for ComplexValType {119	fn from(s: ValType) -> Self {120		Self::Simple(s)121	}122}123124impl ComplexValType {125	fn needs_brackets(&self) -> bool {126		matches!(self, ComplexValType::UnionRef(_) | ComplexValType::SumRef(_))127	}128}129130fn write_union(131	f: &mut std::fmt::Formatter<'_>,132	ch: char,133	union: &[ComplexValType],134) -> std::fmt::Result {135	write!(f, "(")?;136	for (i, v) in union.iter().enumerate() {137		if i != 0 {138			write!(f, " {} ", ch)?;139		}140		write!(f, "{}", v)?;141	}142	write!(f, ")")?;143	Ok(())144}145146impl Display for ComplexValType {147	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {148		match self {149			ComplexValType::Any => write!(f, "any")?,150			ComplexValType::Simple(s) => write!(f, "{}", s)?,151			ComplexValType::Char => write!(f, "char")?,152			ComplexValType::BoundedNumber(a, b) => write!(153				f,154				"number({}..{})",155				a.map(|e| e.to_string()).unwrap_or_else(|| "".into()),156				b.map(|e| e.to_string()).unwrap_or_else(|| "".into())157			)?,158			ComplexValType::ArrayRef(a) => {159				if a.needs_brackets() {160					write!(f, "(")?;161				}162				write!(f, "{}", a)?;163				if a.needs_brackets() {164					write!(f, ")")?;165				}166				write!(f, "[]")?;167			}168			ComplexValType::ObjectRef(fields) => {169				write!(f, "{{")?;170				for (i, (k, v)) in fields.iter().enumerate() {171					if i != 0 {172						write!(f, ", ")?;173					}174					write!(f, "{}: {}", k, v)?;175				}176				write!(f, "}}")?;177			}178			ComplexValType::UnionRef(v) => write_union(f, '|', v)?,179			ComplexValType::SumRef(v) => write_union(f, '&', v)?,180		};181		Ok(())182	}183}