difftreelog
feat peg parsing for types
in: master
3 files changed
crates/jrsonnet-evaluator/src/typed.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/typed.rs
+++ b/crates/jrsonnet-evaluator/src/typed.rs
@@ -158,6 +158,20 @@
Err(TypeError::ExpectedGot(self.clone(), value.value_type()).into())
}
}
+ ComplexValType::Array(elem_type) => match value {
+ Val::Arr(a) => {
+ for (i, item) in a.iter().enumerate() {
+ push_type(
+ &None,
+ || format!("array index {}", i),
+ || ValuePathItem::Index(i as u64),
+ || Ok(elem_type.check(&item.clone()?)?),
+ )?;
+ }
+ Ok(())
+ }
+ v => return Err(TypeError::ExpectedGot(self.clone(), v.value_type()).into()),
+ },
ComplexValType::ArrayRef(elem_type) => match value {
Val::Arr(a) => {
for (i, item) in a.iter().enumerate() {
@@ -192,6 +206,21 @@
}
v => return Err(TypeError::ExpectedGot(self.clone(), v.value_type()).into()),
},
+ ComplexValType::Union(types) => {
+ let mut errors = Vec::new();
+ for ty in types.iter() {
+ match ty.check(value) {
+ Ok(()) => {
+ return Ok(());
+ }
+ Err(e) => match e.error() {
+ Error::TypeError(e) => errors.push(e.clone()),
+ _ => return Err(e),
+ },
+ }
+ }
+ return Err(TypeError::UnionFailed(self.clone(), TypeLocErrorList(errors)).into());
+ }
ComplexValType::UnionRef(types) => {
let mut errors = Vec::new();
for ty in types.iter() {
@@ -207,6 +236,12 @@
}
return Err(TypeError::UnionFailed(self.clone(), TypeLocErrorList(errors)).into());
}
+ ComplexValType::Sum(types) => {
+ for ty in types.iter() {
+ ty.check(value)?
+ }
+ Ok(())
+ }
ComplexValType::SumRef(types) => {
for ty in types.iter() {
ty.check(value)?
crates/jrsonnet-types/Cargo.tomldiffbeforeafterboth--- a/crates/jrsonnet-types/Cargo.toml
+++ b/crates/jrsonnet-types/Cargo.toml
@@ -5,3 +5,4 @@
edition = "2018"
[dependencies]
+peg = "0.6.3"
\ No newline at end of file
crates/jrsonnet-types/src/lib.rsdiffbeforeafterboth1use 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!(format!("{}", ty!(((string & number) | array))), "string & number | array");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 => "boolean",91 Null => "null",92 Str => "string",93 Num => "number",94 Arr => "array",95 Obj => "object",96 Func => "function",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}123124fn write_union(125 f: &mut std::fmt::Formatter<'_>,126 is_union: bool,127 union: &[ComplexValType],128) -> std::fmt::Result {129 for (i, v) in union.iter().enumerate() {130 let should_add_braces = match v {131 ComplexValType::UnionRef(_) if !is_union => true,132 _ => false,133 };134 if i != 0 {135 write!(f, " {} ", if is_union { '|' } else { '&' })?;136 }137 if should_add_braces {138 write!(f, "(")?;139 }140 write!(f, "{}", v)?;141 if should_add_braces {142 write!(f, ")")?;143 }144 }145 Ok(())146}147148impl Display for ComplexValType {149 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {150 match self {151 ComplexValType::Any => write!(f, "any")?,152 ComplexValType::Simple(s) => write!(f, "{}", s)?,153 ComplexValType::Char => write!(f, "char")?,154 ComplexValType::BoundedNumber(a, b) => write!(155 f,156 "BoundedNumber<{}, {}>",157 a.map(|e| e.to_string()).unwrap_or_else(|| "".into()),158 b.map(|e| e.to_string()).unwrap_or_else(|| "".into())159 )?,160 ComplexValType::ArrayRef(a) => {161 if **a == ComplexValType::Any {162 write!(f, "array")?163 } else {164 write!(f, "Array<{}>", a)?165 }166 }167 ComplexValType::ObjectRef(fields) => {168 write!(f, "{{")?;169 for (i, (k, v)) in fields.iter().enumerate() {170 if i != 0 {171 write!(f, ", ")?;172 }173 write!(f, "{}: {}", k, v)?;174 }175 write!(f, "}}")?;176 }177 ComplexValType::UnionRef(v) => write_union(f, true, v)?,178 ComplexValType::SumRef(v) => write_union(f, false, v)?,179 };180 Ok(())181 }182}