git.delta.rocks / jrsonnet / refs/commits / 5e6d5ee048e2

difftreelog

refactor unify throw & throw_runtime

Yaroslav Bolyukin2022-10-17parent: #b8bef13.patch.diff
in: master

13 files changed

modifiedcrates/jrsonnet-evaluator/src/error.rsdiffbeforeafterboth
265pub type Result<V, E = LocError> = std::result::Result<V, E>;265pub type Result<V, E = LocError> = std::result::Result<V, E>;
266266
267#[macro_export]267#[macro_export]
268macro_rules! throw {268macro_rules! throw {
269 ($e: expr) => {269 ($w:ident$(::$i:ident)*$(($($tt:tt)*))?) => {
270 return Err($e.into())270 return Err($w$(::$i)*$(($($tt)*))?.into())
271 };271 };
272}272 ($l:literal) => {
273273 return Err($crate::error::Error::RuntimeError($l.into()).into())
274#[macro_export]274 };
275macro_rules! throw_runtime {
276 ($($tt:tt)*) => {275 ($l:literal, $($tt:tt)*) => {
277 return Err($crate::error::Error::RuntimeError(format!($($tt)*).into()).into())276 return Err($crate::error::Error::RuntimeError(format!($l, $($tt)*).into()).into())
278 };277 };
279}278}
280279
modifiedcrates/jrsonnet-evaluator/src/evaluate/destructure.rsdiffbeforeafterboth
32 Destruct::Array { start, rest, end } => {32 Destruct::Array { start, rest, end } => {
33 use jrsonnet_parser::DestructRest;33 use jrsonnet_parser::DestructRest;
3434
35 use crate::{throw_runtime, val::ArrValue};35 use crate::{throw, val::ArrValue};
3636
37 #[derive(Trace)]37 #[derive(Trace)]
38 struct DataThunk {38 struct DataThunk {
47 let v = self.parent.evaluate(s)?;47 let v = self.parent.evaluate(s)?;
48 let arr = match v {48 let arr = match v {
49 Val::Arr(a) => a,49 Val::Arr(a) => a,
50 _ => throw_runtime!("expected array"),50 _ => throw!("expected array"),
51 };51 };
52 if !self.has_rest {52 if !self.has_rest {
53 if arr.len() != self.min_len {53 if arr.len() != self.min_len {
54 throw_runtime!("expected {} elements, got {}", self.min_len, arr.len())54 throw!("expected {} elements, got {}", self.min_len, arr.len())
55 }55 }
56 } else if arr.len() < self.min_len {56 } else if arr.len() < self.min_len {
57 throw_runtime!(57 throw!(
58 "expected at least {} elements, but array was only {}",58 "expected at least {} elements, but array was only {}",
59 self.min_len,59 self.min_len,
60 arr.len()60 arr.len()
163 }163 }
164 #[cfg(feature = "exp-destruct")]164 #[cfg(feature = "exp-destruct")]
165 Destruct::Object { fields, rest } => {165 Destruct::Object { fields, rest } => {
166 use crate::{obj::ObjValue, throw_runtime};166 use crate::{obj::ObjValue, throw};
167167
168 #[derive(Trace)]168 #[derive(Trace)]
169 struct DataThunk {169 struct DataThunk {
178 let v = self.parent.evaluate(s)?;178 let v = self.parent.evaluate(s)?;
179 let obj = match v {179 let obj = match v {
180 Val::Obj(o) => o,180 Val::Obj(o) => o,
181 _ => throw_runtime!("expected object"),181 _ => throw!("expected object"),
182 };182 };
183 for field in &self.field_names {183 for field in &self.field_names {
184 if !obj.has_field_ex(field.clone(), true) {184 if !obj.has_field_ex(field.clone(), true) {
185 throw_runtime!("missing field: {}", field);185 throw!("missing field: {}", field);
186 }186 }
187 }187 }
188 if !self.has_rest {188 if !self.has_rest {
189 let len = obj.len();189 let len = obj.len();
190 if len != self.field_names.len() {190 if len != self.field_names.len() {
191 throw_runtime!("too many fields, and rest not found");191 throw!("too many fields, and rest not found");
192 }192 }
193 }193 }
194 Ok(obj)194 Ok(obj)
modifiedcrates/jrsonnet-evaluator/src/evaluate/operator.rsdiffbeforeafterboth
150 (Num(v1), BitXor, Num(v2)) => Num(f64::from((*v1 as i32) ^ (*v2 as i32))),150 (Num(v1), BitXor, Num(v2)) => Num(f64::from((*v1 as i32) ^ (*v2 as i32))),
151 (Num(v1), Lhs, Num(v2)) => {151 (Num(v1), Lhs, Num(v2)) => {
152 if *v2 < 0.0 {152 if *v2 < 0.0 {
153 throw!(RuntimeError("shift by negative exponent".into()))153 throw!("shift by negative exponent")
154 }154 }
155 Num(f64::from((*v1 as i32) << (*v2 as i32)))155 Num(f64::from((*v1 as i32) << (*v2 as i32)))
156 }156 }
157 (Num(v1), Rhs, Num(v2)) => {157 (Num(v1), Rhs, Num(v2)) => {
158 if *v2 < 0.0 {158 if *v2 < 0.0 {
159 throw!(RuntimeError("shift by negative exponent".into()))159 throw!("shift by negative exponent")
160 }160 }
161 Num(f64::from((*v1 as i32) >> (*v2 as i32)))161 Num(f64::from((*v1 as i32) >> (*v2 as i32)))
162 }162 }
modifiedcrates/jrsonnet-evaluator/src/integrations/serde.rsdiffbeforeafterboth
72 }72 }
73 Self::Object(out)73 Self::Object(out)
74 }74 }
75 Val::Func(_) => throw!(RuntimeError("tried to manifest function".into())),75 Val::Func(_) => throw!("tried to manifest function"),
76 })76 })
77 }77 }
78}78}
modifiedcrates/jrsonnet-evaluator/src/stdlib/format.rsdiffbeforeafterboth
591 ),591 ),
592 Val::Str(s) => {592 Val::Str(s) => {
593 if s.chars().count() != 1 {593 if s.chars().count() != 1 {
594 throw!(RuntimeError(594 throw!("%c expected 1 char string, got {}", s.chars().count(),);
595 format!("%c expected 1 char string, got {}", s.chars().count()).into(),
596 ));
597 }595 }
598 tmp_out.push_str(&s);596 tmp_out.push_str(&s);
599 }597 }
modifiedcrates/jrsonnet-evaluator/src/stdlib/manifest.rsdiffbeforeafterboth
341 }341 }
342 }342 }
343 }343 }
344 Val::Func(_) => throw!(RuntimeError("tried to manifest function".into())),344 Val::Func(_) => throw!("tried to manifest function"),
345 }345 }
346 Ok(())346 Ok(())
347}347}
modifiedcrates/jrsonnet-evaluator/src/typed/conversions.rsdiffbeforeafterboth
6use jrsonnet_types::{ComplexValType, ValType};6use jrsonnet_types::{ComplexValType, ValType};
77
8use crate::{8use crate::{
9 error::{Error::*, Result},9 error::Result,
10 function::{FuncDesc, FuncVal},10 function::{FuncDesc, FuncVal},
11 throw,11 throw,
12 typed::CheckType,12 typed::CheckType,
41 Val::Num(n) => {41 Val::Num(n) => {
42 #[allow(clippy::float_cmp)]42 #[allow(clippy::float_cmp)]
43 if n.trunc() != n {43 if n.trunc() != n {
44 throw!(RuntimeError(44 throw!(
45 format!(
46 "cannot convert number with fractional part to {}",45 "cannot convert number with fractional part to {}",
47 stringify!($ty)46 stringify!($ty)
48 )
49 .into()
50 ))47 )
51 }48 }
52 Ok(n as Self)49 Ok(n as Self)
53 }50 }
99 Val::Num(n) => {96 Val::Num(n) => {
100 #[allow(clippy::float_cmp)]97 #[allow(clippy::float_cmp)]
101 if n.trunc() != n {98 if n.trunc() != n {
102 throw!(RuntimeError(99 throw!(
103 format!(
104 "cannot convert number with fractional part to {}",100 "cannot convert number with fractional part to {}",
105 stringify!($ty)101 stringify!($ty)
106 )
107 .into()
108 ))102 )
109 }103 }
110 Ok(Self(n as $ty))104 Ok(Self(n as $ty))
111 }105 }
167161
168 fn into_untyped(value: Self, _: State) -> Result<Val> {162 fn into_untyped(value: Self, _: State) -> Result<Val> {
169 if value > u32::MAX as Self {163 if value > u32::MAX as Self {
170 throw!(RuntimeError("number is too large".into()))164 throw!("number is too large")
171 }165 }
172 Ok(Val::Num(value as f64))166 Ok(Val::Num(value as f64))
173 }167 }
178 Val::Num(n) => {172 Val::Num(n) => {
179 #[allow(clippy::float_cmp)]173 #[allow(clippy::float_cmp)]
180 if n.trunc() != n {174 if n.trunc() != n {
181 throw!(RuntimeError(175 throw!("cannot convert number with fractional part to usize")
182 "cannot convert number with fractional part to usize".into()
183 ))
184 }176 }
185 Ok(n as Self)177 Ok(n as Self)
186 }178 }
440 <Self as Typed>::TYPE.check(s, &value)?;432 <Self as Typed>::TYPE.check(s, &value)?;
441 match value {433 match value {
442 Val::Func(FuncVal::Normal(desc)) => Ok(desc),434 Val::Func(FuncVal::Normal(desc)) => Ok(desc),
443 Val::Func(_) => throw!(RuntimeError("expected normal function, not builtin".into())),435 Val::Func(_) => throw!("expected normal function, not builtin"),
444 _ => unreachable!(),436 _ => unreachable!(),
445 }437 }
446 }438 }
modifiedcrates/jrsonnet-evaluator/src/val.rsdiffbeforeafterboth
629 if num.is_finite() {629 if num.is_finite() {
630 Ok(Self::Num(num))630 Ok(Self::Num(num))
631 } else {631 } else {
632 throw!(RuntimeError("overflow".into()))632 throw!("overflow")
633 }633 }
634 }634 }
635635
843 (Val::Null, Val::Null) => true,843 (Val::Null, Val::Null) => true,
844 (Val::Str(a), Val::Str(b)) => a == b,844 (Val::Str(a), Val::Str(b)) => a == b,
845 (Val::Num(a), Val::Num(b)) => (a - b).abs() <= f64::EPSILON,845 (Val::Num(a), Val::Num(b)) => (a - b).abs() <= f64::EPSILON,
846 (Val::Arr(_), Val::Arr(_)) => throw!(RuntimeError(846 (Val::Arr(_), Val::Arr(_)) => {
847 "primitiveEquals operates on primitive types, got array".into(),847 throw!("primitiveEquals operates on primitive types, got array")
848 )),848 }
849 (Val::Obj(_), Val::Obj(_)) => throw!(RuntimeError(849 (Val::Obj(_), Val::Obj(_)) => {
850 "primitiveEquals operates on primitive types, got object".into(),850 throw!("primitiveEquals operates on primitive types, got object")
851 )),851 }
852 (a, b) if is_function_like(a) && is_function_like(b) => {852 (a, b) if is_function_like(a) && is_function_like(b) => {
853 throw!(RuntimeError("cannot test equality of functions".into()))853 throw!("cannot test equality of functions")
854 }854 }
855 (_, _) => false,855 (_, _) => false,
856 })856 })
modifiedcrates/jrsonnet-stdlib/src/arrays.rsdiffbeforeafterboth
1use jrsonnet_evaluator::{1use jrsonnet_evaluator::{
2 error::Result,2 error::Result,
3 function::{builtin, FuncVal},3 function::{builtin, FuncVal},
4 throw_runtime,4 throw,
5 typed::{Any, BoundedUsize, Typed, VecVal},5 typed::{Any, BoundedUsize, Typed, VecVal},
6 val::{equals, ArrValue, IndexableVal},6 val::{equals, ArrValue, IndexableVal},
7 IStr, State, Val,7 IStr, State, Val,
43 match func.evaluate_simple(s.clone(), &(c.to_string(),))? {43 match func.evaluate_simple(s.clone(), &(c.to_string(),))? {
44 Val::Str(o) => out.push_str(&o),44 Val::Str(o) => out.push_str(&o),
45 Val::Null => continue,45 Val::Null => continue,
46 _ => throw_runtime!("in std.join all items should be strings"),46 _ => throw!("in std.join all items should be strings"),
47 };47 };
48 }48 }
49 Ok(IndexableVal::Str(out.into()))49 Ok(IndexableVal::Str(out.into()))
59 }59 }
60 }60 }
61 Val::Null => continue,61 Val::Null => continue,
62 _ => throw_runtime!("in std.join all items should be arrays"),62 _ => throw!("in std.join all items should be arrays"),
63 };63 };
64 }64 }
65 Ok(IndexableVal::Arr(out.into()))65 Ok(IndexableVal::Arr(out.into()))
128 } else if matches!(item, Val::Null) {128 } else if matches!(item, Val::Null) {
129 continue;129 continue;
130 } else {130 } else {
131 throw_runtime!("in std.join all items should be arrays");131 throw!("in std.join all items should be arrays");
132 }132 }
133 }133 }
134134
149 } else if matches!(item, Val::Null) {149 } else if matches!(item, Val::Null) {
150 continue;150 continue;
151 } else {151 } else {
152 throw_runtime!("in std.join all items should be strings");152 throw!("in std.join all items should be strings");
153 }153 }
154 }154 }
155155
modifiedcrates/jrsonnet-stdlib/src/lib.rsdiffbeforeafterboth
8 error::{Error::*, Result},8 error::{Error::*, Result},
9 function::{builtin::Builtin, ArgLike, CallLocation, FuncVal, TlaArg},9 function::{builtin::Builtin, ArgLike, CallLocation, FuncVal, TlaArg},
10 gc::{GcHashMap, TraceBox},10 gc::{GcHashMap, TraceBox},
11 tb, throw_runtime,11 tb, throw,
12 trace::PathResolver,12 trace::PathResolver,
13 typed::{Any, Either, Either2, Either4, VecVal, M1},13 typed::{Any, Either, Either2, Either4, VecVal, M1},
14 val::{equals, ArrValue},14 val::{equals, ArrValue},
500 true500 true
501 }501 }
502 }502 }
503 _ => throw_runtime!("both arguments should be of the same type"),503 _ => throw!("both arguments should be of the same type"),
504 })504 })
505}505}
506506
534 true534 true
535 }535 }
536 }536 }
537 _ => throw_runtime!("both arguments should be of the same type"),537 _ => throw!("both arguments should be of the same type"),
538 })538 })
539}539}
540540
modifiedcrates/jrsonnet-stdlib/src/sort.rsdiffbeforeafterboth
1use jrsonnet_evaluator::{1use jrsonnet_evaluator::{
2 error::Result,2 error::Result,
3 function::{builtin, FuncVal},3 function::{builtin, FuncVal},
4 throw_runtime,4 throw,
5 typed::Any,5 typed::Any,
6 val::ArrValue,6 val::ArrValue,
7 State, Val,7 State, Val,
41 (Val::Num(_), SortKeyType::Unknown) => sort_type = SortKeyType::Number,41 (Val::Num(_), SortKeyType::Unknown) => sort_type = SortKeyType::Number,
42 (Val::Str(_), SortKeyType::String) | (Val::Num(_), SortKeyType::Number) => {}42 (Val::Str(_), SortKeyType::String) | (Val::Num(_), SortKeyType::Number) => {}
43 (Val::Str(_) | Val::Num(_), _) => {43 (Val::Str(_) | Val::Num(_), _) => {
44 throw_runtime!("sort elements should have the same types")44 throw!("sort elements should have the same types")
45 }45 }
46 _ => throw_runtime!("sort key should either be a string or a number"),46 _ => throw!("sort key should either be a string or a number"),
47 }47 }
48 }48 }
49 Ok(sort_type)49 Ok(sort_type)
modifiedtests/tests/common.rsdiffbeforeafterboth
1use jrsonnet_evaluator::{1use jrsonnet_evaluator::{
2 error::Result,2 error::Result,
3 function::{builtin, FuncVal},3 function::{builtin, FuncVal},
4 throw_runtime, ObjValueBuilder, State, Thunk, Val,4 throw, ObjValueBuilder, State, Thunk, Val,
5};5};
6use jrsonnet_stdlib::StateExt;6use jrsonnet_stdlib::StateExt;
77
11 let a = &$a;11 let a = &$a;
12 let b = &$b;12 let b = &$b;
13 if a != b {13 if a != b {
14 ::jrsonnet_evaluator::throw_runtime!("assertion failed: a != b\na={:#?}\nb={:#?}", a, b)14 ::jrsonnet_evaluator::throw!("assertion failed: a != b\na={:#?}\nb={:#?}", a, b)
15 }15 }
16 }};16 }};
17}17}
20macro_rules! ensure {20macro_rules! ensure {
21 ($v:expr $(,)?) => {21 ($v:expr $(,)?) => {
22 if !$v {22 if !$v {
23 ::jrsonnet_evaluator::throw_runtime!("assertion failed: {}", stringify!($v))23 ::jrsonnet_evaluator::throw!("assertion failed: {}", stringify!($v))
24 }24 }
25 };25 };
26}26}
29macro_rules! ensure_val_eq {29macro_rules! ensure_val_eq {
30 ($s:expr, $a:expr, $b:expr) => {{30 ($s:expr, $a:expr, $b:expr) => {{
31 if !::jrsonnet_evaluator::val::equals($s.clone(), &$a.clone(), &$b.clone())? {31 if !::jrsonnet_evaluator::val::equals($s.clone(), &$a.clone(), &$b.clone())? {
32 ::jrsonnet_evaluator::throw_runtime!(32 ::jrsonnet_evaluator::throw!(
33 "assertion failed: a != b\na={:#?}\nb={:#?}",33 "assertion failed: a != b\na={:#?}\nb={:#?}",
34 $a.to_json(34 $a.to_json(
35 $s.clone(),35 $s.clone(),
52fn assert_throw(s: State, lazy: Thunk<Val>, message: String) -> Result<bool> {52fn assert_throw(s: State, lazy: Thunk<Val>, message: String) -> Result<bool> {
53 match lazy.evaluate(s) {53 match lazy.evaluate(s) {
54 Ok(_) => {54 Ok(_) => {
55 throw_runtime!("expected argument to throw on evaluation, but it returned instead")55 throw!("expected argument to throw on evaluation, but it returned instead")
56 }56 }
57 Err(e) => {57 Err(e) => {
58 let error = format!("{}", e.error());58 let error = format!("{}", e.error());
modifiedtests/tests/sanity.rsdiffbeforeafterboth
1use jrsonnet_evaluator::{error::Result, throw_runtime, State, Val};1use jrsonnet_evaluator::{error::Result, throw, State, Val};
2use jrsonnet_stdlib::StateExt;2use jrsonnet_stdlib::StateExt;
33
4mod common;4mod common;
2323
24 {24 {
25 let e = match s.evaluate_snippet("snip".to_owned(), "assert 1 == 2: 'fail'; null") {25 let e = match s.evaluate_snippet("snip".to_owned(), "assert 1 == 2: 'fail'; null") {
26 Ok(_) => throw_runtime!("assertion should fail"),26 Ok(_) => throw!("assertion should fail"),
27 Err(e) => e,27 Err(e) => e,
28 };28 };
29 let e = s.stringify_err(&e);29 let e = s.stringify_err(&e);
30 ensure!(e.starts_with("assert failed: fail\n"));30 ensure!(e.starts_with("assert failed: fail\n"));
31 }31 }
32 {32 {
33 let e = match s.evaluate_snippet("snip".to_owned(), "std.assertEqual(1, 2)") {33 let e = match s.evaluate_snippet("snip".to_owned(), "std.assertEqual(1, 2)") {
34 Ok(_) => throw_runtime!("assertion should fail"),34 Ok(_) => throw!("assertion should fail"),
35 Err(e) => e,35 Err(e) => e,
36 };36 };
37 let e = s.stringify_err(&e);37 let e = s.stringify_err(&e);