difftreelog
style reformat code
in: master
3 files changed
crates/jrsonnet-evaluator/src/builtin/mod.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/builtin/mod.rs
+++ b/crates/jrsonnet-evaluator/src/builtin/mod.rs
@@ -453,7 +453,6 @@
})
}
-
fn builtin_join(context: Context, _loc: &Option<ExprLocation>, args: &ArgsDesc) -> Result<Val> {
parse_args!(context, "join", args, 2, [
0, sep: ty!((string | array));
@@ -559,7 +558,11 @@
}
// faster
-fn builtin_str_replace(context: Context, _loc: &Option<ExprLocation>, args: &ArgsDesc) -> Result<Val> {
+fn builtin_str_replace(
+ context: Context,
+ _loc: &Option<ExprLocation>,
+ args: &ArgsDesc,
+) -> Result<Val> {
parse_args!(context, "strReplace", args, 3, [
0, str: ty!(string) => Val::Str;
1, from: ty!(string) => Val::Str;
crates/jrsonnet-evaluator/src/typed.rsdiffbeforeafterboth1use std::{fmt::Display, rc::Rc};23use crate::{4 error::{Error, LocError, Result},5 push, Val,6};7use jrsonnet_parser::ExprLocation;8use jrsonnet_types::{ComplexValType, ValType};9use thiserror::Error;1011#[derive(Debug, Error, Clone)]12pub enum TypeError {13 #[error("expected {0}, got {1}")]14 ExpectedGot(ComplexValType, ValType),15 #[error("missing property {0} from {1:?}")]16 MissingProperty(Rc<str>, ComplexValType),17 #[error("every failed from {0}:\n{1}")]18 UnionFailed(ComplexValType, TypeLocErrorList),19 #[error("number out of bounds: {0} not in {1:?}..{2:?}")]20 BoundsFailed(f64, Option<f64>, Option<f64>),21}22impl From<TypeError> for LocError {23 fn from(e: TypeError) -> Self {24 Error::TypeError(e.into()).into()25 }26}2728#[derive(Debug, Clone)]29pub struct TypeLocError(Box<TypeError>, ValuePathStack);30impl From<TypeError> for TypeLocError {31 fn from(e: TypeError) -> Self {32 TypeLocError(Box::new(e), ValuePathStack(Vec::new()))33 }34}35impl From<TypeLocError> for LocError {36 fn from(e: TypeLocError) -> Self {37 Error::TypeError(e).into()38 }39}40impl Display for TypeLocError {41 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {42 write!(f, "{}", self.0)?;43 if !(self.1).0.is_empty() {44 write!(f, "at {}", self.1)?;45 }46 Ok(())47 }48}4950#[derive(Debug, Clone)]51pub struct TypeLocErrorList(Vec<TypeLocError>);52impl Display for TypeLocErrorList {53 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {54 use std::fmt::Write;55 let mut out = String::new();56 for (i, err) in self.0.iter().enumerate() {57 if i != 0 {58 writeln!(f)?;59 }60 out.clear();61 write!(out, "{}", err)?;6263 for (i, line) in out.lines().enumerate() {64 if line.trim().len() == 0 {65 continue;66 }67 if i != 0 {68 writeln!(f)?;69 write!(f, " ")?;70 } else {71 write!(f, " - ")?;72 }73 write!(f, "{}", line)?;74 }75 }76 Ok(())77 }78}7980fn push_type(81 location: &Option<ExprLocation>,82 error_reason: impl Fn() -> String,83 path: impl Fn() -> ValuePathItem,84 item: impl Fn() -> Result<()>,85) -> Result<()> {86 push(location, error_reason, || match item() {87 Ok(_) => Ok(()),88 Err(mut e) => {89 if let Error::TypeError(e) = &mut e.error_mut() {90 (e.1).0.push(path())91 }92 Err(e)93 }94 })95}9697// TODO: check_fast for fast path of union type checking98pub trait CheckType {99 fn check(&self, value: &Val) -> Result<()>;100}101102impl CheckType for ValType {103 fn check(&self, value: &Val) -> Result<()> {104 let got = value.value_type();105 if got != *self {106 let loc_error: TypeLocError = TypeError::ExpectedGot((*self).into(), got).into();107 return Err(loc_error.into());108 }109 Ok(())110 }111}112113#[derive(Clone, Debug)]114enum ValuePathItem {115 Field(Rc<str>),116 Index(u64),117}118impl Display for ValuePathItem {119 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {120 match self {121 ValuePathItem::Field(name) => write!(f, ".{}", name)?,122 ValuePathItem::Index(idx) => write!(f, "[{}]", idx)?,123 }124 Ok(())125 }126}127128#[derive(Clone, Debug)]129struct ValuePathStack(Vec<ValuePathItem>);130impl Display for ValuePathStack {131 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {132 write!(f, "self")?;133 for elem in self.0.iter().rev() {134 write!(f, "{}", elem)?;135 }136 Ok(())137 }138}139140impl CheckType for ComplexValType {141 fn check(&self, value: &Val) -> Result<()> {142 match self {143 ComplexValType::Any => Ok(()),144 ComplexValType::Simple(s) => s.check(value),145 ComplexValType::Char => match value {146 Val::Str(s) if s.chars().count() == 1 => Ok(()),147 v => Err(TypeError::ExpectedGot(self.clone(), v.value_type()).into()),148 },149 ComplexValType::BoundedNumber(from, to) => {150 if let Val::Num(n) = value {151 if from.map(|from| from > *n).unwrap_or(false)152 || to.map(|to| to <= *n).unwrap_or(false)153 {154 return Err(TypeError::BoundsFailed(*n, from.clone(), to.clone()).into());155 }156 Ok(())157 } else {158 Err(TypeError::ExpectedGot(self.clone(), value.value_type()).into())159 }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 },175 ComplexValType::ArrayRef(elem_type) => match value {176 Val::Arr(a) => {177 for (i, item) in a.iter().enumerate() {178 push_type(179 &None,180 || format!("array index {}", i),181 || ValuePathItem::Index(i as u64),182 || Ok(elem_type.check(&item.clone()?)?),183 )?;184 }185 Ok(())186 }187 v => return Err(TypeError::ExpectedGot(self.clone(), v.value_type()).into()),188 },189 ComplexValType::ObjectRef(elems) => match value {190 Val::Obj(obj) => {191 for (k, v) in elems.iter() {192 if let Some(got_v) = obj.get((*k).into())? {193 push_type(194 &None,195 || format!("property {}", k),196 || ValuePathItem::Field((*k).into()),197 || v.check(&got_v),198 )?199 } else {200 return Err(201 TypeError::MissingProperty((*k).into(), self.clone()).into()202 );203 }204 }205 return Ok(());206 }207 v => return Err(TypeError::ExpectedGot(self.clone(), v.value_type()).into()),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 }224 ComplexValType::UnionRef(types) => {225 let mut errors = Vec::new();226 for ty in types.iter() {227 match ty.check(value) {228 Ok(()) => {229 return Ok(());230 }231 Err(e) => match e.error() {232 Error::TypeError(e) => errors.push(e.clone()),233 _ => return Err(e),234 },235 }236 }237 return Err(TypeError::UnionFailed(self.clone(), TypeLocErrorList(errors)).into());238 }239 ComplexValType::Sum(types) => {240 for ty in types.iter() {241 ty.check(value)?242 }243 Ok(())244 }245 ComplexValType::SumRef(types) => {246 for ty in types.iter() {247 ty.check(value)?248 }249 Ok(())250 }251 }252 }253}1use std::{fmt::Display, rc::Rc};23use crate::{4 error::{Error, LocError, Result},5 push, Val,6};7use jrsonnet_parser::ExprLocation;8use jrsonnet_types::{ComplexValType, ValType};9use thiserror::Error;1011#[derive(Debug, Error, Clone)]12pub enum TypeError {13 #[error("expected {0}, got {1}")]14 ExpectedGot(ComplexValType, ValType),15 #[error("missing property {0} from {1:?}")]16 MissingProperty(Rc<str>, ComplexValType),17 #[error("every failed from {0}:\n{1}")]18 UnionFailed(ComplexValType, TypeLocErrorList),19 #[error("number out of bounds: {0} not in {1:?}..{2:?}")]20 BoundsFailed(f64, Option<f64>, Option<f64>),21}22impl From<TypeError> for LocError {23 fn from(e: TypeError) -> Self {24 Error::TypeError(e.into()).into()25 }26}2728#[derive(Debug, Clone)]29pub struct TypeLocError(Box<TypeError>, ValuePathStack);30impl From<TypeError> for TypeLocError {31 fn from(e: TypeError) -> Self {32 TypeLocError(Box::new(e), ValuePathStack(Vec::new()))33 }34}35impl From<TypeLocError> for LocError {36 fn from(e: TypeLocError) -> Self {37 Error::TypeError(e).into()38 }39}40impl Display for TypeLocError {41 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {42 write!(f, "{}", self.0)?;43 if !(self.1).0.is_empty() {44 write!(f, "at {}", self.1)?;45 }46 Ok(())47 }48}4950#[derive(Debug, Clone)]51pub struct TypeLocErrorList(Vec<TypeLocError>);52impl Display for TypeLocErrorList {53 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {54 use std::fmt::Write;55 let mut out = String::new();56 for (i, err) in self.0.iter().enumerate() {57 if i != 0 {58 writeln!(f)?;59 }60 out.clear();61 write!(out, "{}", err)?;6263 for (i, line) in out.lines().enumerate() {64 if line.trim().len() == 0 {65 continue;66 }67 if i != 0 {68 writeln!(f)?;69 write!(f, " ")?;70 } else {71 write!(f, " - ")?;72 }73 write!(f, "{}", line)?;74 }75 }76 Ok(())77 }78}7980fn push_type(81 location: &Option<ExprLocation>,82 error_reason: impl Fn() -> String,83 path: impl Fn() -> ValuePathItem,84 item: impl Fn() -> Result<()>,85) -> Result<()> {86 push(location, error_reason, || match item() {87 Ok(_) => Ok(()),88 Err(mut e) => {89 if let Error::TypeError(e) = &mut e.error_mut() {90 (e.1).0.push(path())91 }92 Err(e)93 }94 })95}9697// TODO: check_fast for fast path of union type checking98pub trait CheckType {99 fn check(&self, value: &Val) -> Result<()>;100}101102impl CheckType for ValType {103 fn check(&self, value: &Val) -> Result<()> {104 let got = value.value_type();105 if got != *self {106 let loc_error: TypeLocError = TypeError::ExpectedGot((*self).into(), got).into();107 return Err(loc_error.into());108 }109 Ok(())110 }111}112113#[derive(Clone, Debug)]114enum ValuePathItem {115 Field(Rc<str>),116 Index(u64),117}118impl Display for ValuePathItem {119 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {120 match self {121 ValuePathItem::Field(name) => write!(f, ".{}", name)?,122 ValuePathItem::Index(idx) => write!(f, "[{}]", idx)?,123 }124 Ok(())125 }126}127128#[derive(Clone, Debug)]129struct ValuePathStack(Vec<ValuePathItem>);130impl Display for ValuePathStack {131 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {132 write!(f, "self")?;133 for elem in self.0.iter().rev() {134 write!(f, "{}", elem)?;135 }136 Ok(())137 }138}139140impl CheckType for ComplexValType {141 fn check(&self, value: &Val) -> Result<()> {142 match self {143 ComplexValType::Any => Ok(()),144 ComplexValType::Simple(s) => s.check(value),145 ComplexValType::Char => match value {146 Val::Str(s) if s.len() == 1 || s.chars().count() == 1 => Ok(()),147 v => Err(TypeError::ExpectedGot(self.clone(), v.value_type()).into()),148 },149 ComplexValType::BoundedNumber(from, to) => {150 if let Val::Num(n) = value {151 if from.map(|from| from > *n).unwrap_or(false)152 || to.map(|to| to <= *n).unwrap_or(false)153 {154 return Err(TypeError::BoundsFailed(*n, from.clone(), to.clone()).into());155 }156 Ok(())157 } else {158 Err(TypeError::ExpectedGot(self.clone(), value.value_type()).into())159 }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 },175 ComplexValType::ArrayRef(elem_type) => match value {176 Val::Arr(a) => {177 for (i, item) in a.iter().enumerate() {178 push_type(179 &None,180 || format!("array index {}", i),181 || ValuePathItem::Index(i as u64),182 || Ok(elem_type.check(&item.clone()?)?),183 )?;184 }185 Ok(())186 }187 v => return Err(TypeError::ExpectedGot(self.clone(), v.value_type()).into()),188 },189 ComplexValType::ObjectRef(elems) => match value {190 Val::Obj(obj) => {191 for (k, v) in elems.iter() {192 if let Some(got_v) = obj.get((*k).into())? {193 push_type(194 &None,195 || format!("property {}", k),196 || ValuePathItem::Field((*k).into()),197 || v.check(&got_v),198 )?199 } else {200 return Err(201 TypeError::MissingProperty((*k).into(), self.clone()).into()202 );203 }204 }205 return Ok(());206 }207 v => return Err(TypeError::ExpectedGot(self.clone(), v.value_type()).into()),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 }224 ComplexValType::UnionRef(types) => {225 let mut errors = Vec::new();226 for ty in types.iter() {227 match ty.check(value) {228 Ok(()) => {229 return Ok(());230 }231 Err(e) => match e.error() {232 Error::TypeError(e) => errors.push(e.clone()),233 _ => return Err(e),234 },235 }236 }237 return Err(TypeError::UnionFailed(self.clone(), TypeLocErrorList(errors)).into());238 }239 ComplexValType::Sum(types) => {240 for ty in types.iter() {241 ty.check(value)?242 }243 Ok(())244 }245 ComplexValType::SumRef(types) => {246 for ty in types.iter() {247 ty.check(value)?248 }249 Ok(())250 }251 }252 }253}crates/jrsonnet-types/src/lib.rsdiffbeforeafterboth--- a/crates/jrsonnet-types/src/lib.rs
+++ b/crates/jrsonnet-types/src/lib.rs
@@ -69,7 +69,10 @@
"string & number | object & null"
);
assert_eq!(format!("{}", ty!((string | array))), "string | array");
- assert_eq!(format!("{}", ty!(((string & number) | array))), "string & number | array");
+ assert_eq!(
+ format!("{}", ty!(((string & number) | array))),
+ "string & number | array"
+ );
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
@@ -190,7 +193,7 @@
}
}
-peg::parser!{
+peg::parser! {
pub grammar parser() for str {
rule number() -> f64
= n:$(['0'..='9']+) { n.parse().unwrap() }
@@ -204,7 +207,7 @@
rule simple_array_ty() -> ComplexValType = "array" { ComplexValType::Simple(ValType::Arr) }
rule simple_object_ty() -> ComplexValType = "object" { ComplexValType::Simple(ValType::Obj) }
rule simple_function_ty() -> ComplexValType = "function" { ComplexValType::Simple(ValType::Func) }
-
+
rule array_ty() -> ComplexValType
= "Array<" t:ty() ">" { ComplexValType::Array(Box::new(t)) }
@@ -258,16 +261,27 @@
#[test]
fn precedence() {
- assert_eq!(parser::ty("(any & any) | (any | any) & any").unwrap().to_string(), "any & any | (any | any) & any");
+ assert_eq!(
+ parser::ty("(any & any) | (any | any) & any")
+ .unwrap()
+ .to_string(),
+ "any & any | (any | any) & any"
+ );
}
#[test]
fn array() {
assert_eq!(parser::ty("Array<any>").unwrap().to_string(), "array");
- assert_eq!(parser::ty("Array<number>").unwrap().to_string(), "Array<number>");
+ assert_eq!(
+ parser::ty("Array<number>").unwrap().to_string(),
+ "Array<number>"
+ );
}
#[test]
fn bounded_number() {
- assert_eq!(parser::ty("BoundedNumber<1, 2>").unwrap().to_string(), "BoundedNumber<1, 2>");
+ assert_eq!(
+ parser::ty("BoundedNumber<1, 2>").unwrap().to_string(),
+ "BoundedNumber<1, 2>"
+ );
}
-}
\ No newline at end of file
+}