difftreelog
feat peg parsing for types
in: master
3 files changed
crates/jrsonnet-evaluator/src/typed.rsdiffbeforeafterboth158 Err(TypeError::ExpectedGot(self.clone(), value.value_type()).into())158 Err(TypeError::ExpectedGot(self.clone(), value.value_type()).into())159 }159 }160 }160 }161 ComplexValType::Array(elem_type) => match value {162 Val::Arr(a) => {163 for (i, item) in a.iter().enumerate() {164 push_type(165 &None,166 || format!("array index {}", i),167 || ValuePathItem::Index(i as u64),168 || Ok(elem_type.check(&item.clone()?)?),169 )?;170 }171 Ok(())172 }173 v => return Err(TypeError::ExpectedGot(self.clone(), v.value_type()).into()),174 },161 ComplexValType::ArrayRef(elem_type) => match value {175 ComplexValType::ArrayRef(elem_type) => match value {162 Val::Arr(a) => {176 Val::Arr(a) => {163 for (i, item) in a.iter().enumerate() {177 for (i, item) in a.iter().enumerate() {192 }206 }193 v => return Err(TypeError::ExpectedGot(self.clone(), v.value_type()).into()),207 v => return Err(TypeError::ExpectedGot(self.clone(), v.value_type()).into()),194 },208 },209 ComplexValType::Union(types) => {210 let mut errors = Vec::new();211 for ty in types.iter() {212 match ty.check(value) {213 Ok(()) => {214 return Ok(());215 }216 Err(e) => match e.error() {217 Error::TypeError(e) => errors.push(e.clone()),218 _ => return Err(e),219 },220 }221 }222 return Err(TypeError::UnionFailed(self.clone(), TypeLocErrorList(errors)).into());223 }195 ComplexValType::UnionRef(types) => {224 ComplexValType::UnionRef(types) => {196 let mut errors = Vec::new();225 let mut errors = Vec::new();197 for ty in types.iter() {226 for ty in types.iter() {207 }236 }208 return Err(TypeError::UnionFailed(self.clone(), TypeLocErrorList(errors)).into());237 return Err(TypeError::UnionFailed(self.clone(), TypeLocErrorList(errors)).into());209 }238 }239 ComplexValType::Sum(types) => {240 for ty in types.iter() {241 ty.check(value)?242 }243 Ok(())244 }210 ComplexValType::SumRef(types) => {245 ComplexValType::SumRef(types) => {211 for ty in types.iter() {246 for ty in types.iter() {212 ty.check(value)?247 ty.check(value)?crates/jrsonnet-types/Cargo.tomldiffbeforeafterboth5edition = "2018"5edition = "2018"667[dependencies]7[dependencies]88peg = "0.6.3"crates/jrsonnet-types/src/lib.rsdiffbeforeafterboth110 Char,110 Char,111 Simple(ValType),111 Simple(ValType),112 BoundedNumber(Option<f64>, Option<f64>),112 BoundedNumber(Option<f64>, Option<f64>),113 Array(Box<ComplexValType>),113 ArrayRef(&'static ComplexValType),114 ArrayRef(&'static ComplexValType),114 ObjectRef(&'static [(&'static str, ComplexValType)]),115 ObjectRef(&'static [(&'static str, ComplexValType)]),116 Union(Vec<ComplexValType>),115 UnionRef(&'static [ComplexValType]),117 UnionRef(&'static [ComplexValType]),118 Sum(Vec<ComplexValType>),116 SumRef(&'static [ComplexValType]),119 SumRef(&'static [ComplexValType]),117}120}118impl From<ValType> for ComplexValType {121impl From<ValType> for ComplexValType {128) -> std::fmt::Result {131) -> std::fmt::Result {129 for (i, v) in union.iter().enumerate() {132 for (i, v) in union.iter().enumerate() {130 let should_add_braces = match v {133 let should_add_braces = match v {131 ComplexValType::UnionRef(_) if !is_union => true,134 ComplexValType::UnionRef(_) | ComplexValType::Union(_) if !is_union => true,132 _ => false,135 _ => false,133 };136 };134 if i != 0 {137 if i != 0 {145 Ok(())148 Ok(())146}149}150151fn print_array(a: &ComplexValType, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {152 if *a == ComplexValType::Any {153 write!(f, "array")?154 } else {155 write!(f, "Array<{}>", a)?156 }157 Ok(())158}147159148impl Display for ComplexValType {160impl Display for ComplexValType {149 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {161 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {157 a.map(|e| e.to_string()).unwrap_or_else(|| "".into()),169 a.map(|e| e.to_string()).unwrap_or_else(|| "".into()),158 b.map(|e| e.to_string()).unwrap_or_else(|| "".into())170 b.map(|e| e.to_string()).unwrap_or_else(|| "".into())159 )?,171 )?,160 ComplexValType::ArrayRef(a) => {172 ComplexValType::ArrayRef(a) => print_array(a, f)?,161 if **a == ComplexValType::Any {173 ComplexValType::Array(a) => print_array(a, f)?,162 write!(f, "array")?163 } else {164 write!(f, "Array<{}>", a)?165 }166 }167 ComplexValType::ObjectRef(fields) => {174 ComplexValType::ObjectRef(fields) => {168 write!(f, "{{")?;175 write!(f, "{{")?;169 for (i, (k, v)) in fields.iter().enumerate() {176 for (i, (k, v)) in fields.iter().enumerate() {174 }181 }175 write!(f, "}}")?;182 write!(f, "}}")?;176 }183 }184 ComplexValType::Union(v) => write_union(f, true, v)?,177 ComplexValType::UnionRef(v) => write_union(f, true, v)?,185 ComplexValType::UnionRef(v) => write_union(f, true, v)?,186 ComplexValType::Sum(v) => write_union(f, false, v)?,178 ComplexValType::SumRef(v) => write_union(f, false, v)?,187 ComplexValType::SumRef(v) => write_union(f, false, v)?,179 };188 };180 Ok(())189 Ok(())181 }190 }182}191}183192193peg::parser!{194pub grammar parser() for str {195 rule number() -> f64196 = n:$(['0'..='9']+) { n.parse().unwrap() }197198 rule any_ty() -> ComplexValType = "any" { ComplexValType::Any }199 rule char_ty() -> ComplexValType = "character" { ComplexValType::Char }200 rule bool_ty() -> ComplexValType = "boolean" { ComplexValType::Simple(ValType::Bool) }201 rule null_ty() -> ComplexValType = "null" { ComplexValType::Simple(ValType::Null) }202 rule str_ty() -> ComplexValType = "string" { ComplexValType::Simple(ValType::Str) }203 rule num_ty() -> ComplexValType = "number" { ComplexValType::Simple(ValType::Num) }204 rule simple_array_ty() -> ComplexValType = "array" { ComplexValType::Simple(ValType::Arr) }205 rule simple_object_ty() -> ComplexValType = "object" { ComplexValType::Simple(ValType::Obj) }206 rule simple_function_ty() -> ComplexValType = "function" { ComplexValType::Simple(ValType::Func) }207 208 rule array_ty() -> ComplexValType209 = "Array<" t:ty() ">" { ComplexValType::Array(Box::new(t)) }210211 rule bounded_number_ty() -> ComplexValType212 = "BoundedNumber<" a:number() ", " b:number() ">" { ComplexValType::BoundedNumber(Some(a), Some(b)) }213214 rule ty_basic() -> ComplexValType215 = any_ty()216 / char_ty()217 / bool_ty()218 / null_ty()219 / str_ty()220 / num_ty()221 / simple_array_ty()222 / simple_object_ty()223 / simple_function_ty()224 / array_ty()225 / bounded_number_ty()226227 pub rule ty() -> ComplexValType228 = precedence! {229 a:(@) " | " b:@ {230 match a {231 ComplexValType::Union(mut a) => {232 a.push(b);233 ComplexValType::Union(a)234 }235 _ => ComplexValType::Union(vec![a, b]),236 }237 }238 --239 a:(@) " & " b:@ {240 match a {241 ComplexValType::Sum(mut a) => {242 a.push(b);243 ComplexValType::Sum(a)244 }245 _ => ComplexValType::Sum(vec![a, b]),246 }247 }248 --249 "(" t:ty() ")" { t }250 t:ty_basic() { t }251 }252}253}254255#[cfg(test)]256pub mod tests {257 use super::parser;258259 #[test]260 fn precedence() {261 assert_eq!(parser::ty("(any & any) | (any | any) & any").unwrap().to_string(), "any & any | (any | any) & any");262 }263264 #[test]265 fn array() {266 assert_eq!(parser::ty("Array<any>").unwrap().to_string(), "array");267 assert_eq!(parser::ty("Array<number>").unwrap().to_string(), "Array<number>");268 }269 #[test]270 fn bounded_number() {271 assert_eq!(parser::ty("BoundedNumber<1, 2>").unwrap().to_string(), "BoundedNumber<1, 2>");272 }273}