difftreelog
refactor unify throw & throw_runtime
in: master
13 files changed
crates/jrsonnet-evaluator/src/error.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/error.rs
+++ b/crates/jrsonnet-evaluator/src/error.rs
@@ -266,14 +266,13 @@
#[macro_export]
macro_rules! throw {
- ($e: expr) => {
- return Err($e.into())
+ ($w:ident$(::$i:ident)*$(($($tt:tt)*))?) => {
+ return Err($w$(::$i)*$(($($tt)*))?.into())
};
-}
-
-#[macro_export]
-macro_rules! throw_runtime {
- ($($tt:tt)*) => {
- return Err($crate::error::Error::RuntimeError(format!($($tt)*).into()).into())
+ ($l:literal) => {
+ return Err($crate::error::Error::RuntimeError($l.into()).into())
+ };
+ ($l:literal, $($tt:tt)*) => {
+ return Err($crate::error::Error::RuntimeError(format!($l, $($tt)*).into()).into())
};
}
crates/jrsonnet-evaluator/src/evaluate/destructure.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/evaluate/destructure.rs
+++ b/crates/jrsonnet-evaluator/src/evaluate/destructure.rs
@@ -32,7 +32,7 @@
Destruct::Array { start, rest, end } => {
use jrsonnet_parser::DestructRest;
- use crate::{throw_runtime, val::ArrValue};
+ use crate::{throw, val::ArrValue};
#[derive(Trace)]
struct DataThunk {
@@ -47,14 +47,14 @@
let v = self.parent.evaluate(s)?;
let arr = match v {
Val::Arr(a) => a,
- _ => throw_runtime!("expected array"),
+ _ => throw!("expected array"),
};
if !self.has_rest {
if arr.len() != self.min_len {
- throw_runtime!("expected {} elements, got {}", self.min_len, arr.len())
+ throw!("expected {} elements, got {}", self.min_len, arr.len())
}
} else if arr.len() < self.min_len {
- throw_runtime!(
+ throw!(
"expected at least {} elements, but array was only {}",
self.min_len,
arr.len()
@@ -163,7 +163,7 @@
}
#[cfg(feature = "exp-destruct")]
Destruct::Object { fields, rest } => {
- use crate::{obj::ObjValue, throw_runtime};
+ use crate::{obj::ObjValue, throw};
#[derive(Trace)]
struct DataThunk {
@@ -178,17 +178,17 @@
let v = self.parent.evaluate(s)?;
let obj = match v {
Val::Obj(o) => o,
- _ => throw_runtime!("expected object"),
+ _ => throw!("expected object"),
};
for field in &self.field_names {
if !obj.has_field_ex(field.clone(), true) {
- throw_runtime!("missing field: {}", field);
+ throw!("missing field: {}", field);
}
}
if !self.has_rest {
let len = obj.len();
if len != self.field_names.len() {
- throw_runtime!("too many fields, and rest not found");
+ throw!("too many fields, and rest not found");
}
}
Ok(obj)
crates/jrsonnet-evaluator/src/evaluate/operator.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/evaluate/operator.rs
+++ b/crates/jrsonnet-evaluator/src/evaluate/operator.rs
@@ -150,13 +150,13 @@
(Num(v1), BitXor, Num(v2)) => Num(f64::from((*v1 as i32) ^ (*v2 as i32))),
(Num(v1), Lhs, Num(v2)) => {
if *v2 < 0.0 {
- throw!(RuntimeError("shift by negative exponent".into()))
+ throw!("shift by negative exponent")
}
Num(f64::from((*v1 as i32) << (*v2 as i32)))
}
(Num(v1), Rhs, Num(v2)) => {
if *v2 < 0.0 {
- throw!(RuntimeError("shift by negative exponent".into()))
+ throw!("shift by negative exponent")
}
Num(f64::from((*v1 as i32) >> (*v2 as i32)))
}
crates/jrsonnet-evaluator/src/integrations/serde.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/integrations/serde.rs
+++ b/crates/jrsonnet-evaluator/src/integrations/serde.rs
@@ -72,7 +72,7 @@
}
Self::Object(out)
}
- Val::Func(_) => throw!(RuntimeError("tried to manifest function".into())),
+ Val::Func(_) => throw!("tried to manifest function"),
})
}
}
crates/jrsonnet-evaluator/src/stdlib/format.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/stdlib/format.rs
+++ b/crates/jrsonnet-evaluator/src/stdlib/format.rs
@@ -591,9 +591,7 @@
),
Val::Str(s) => {
if s.chars().count() != 1 {
- throw!(RuntimeError(
- format!("%c expected 1 char string, got {}", s.chars().count()).into(),
- ));
+ throw!("%c expected 1 char string, got {}", s.chars().count(),);
}
tmp_out.push_str(&s);
}
crates/jrsonnet-evaluator/src/stdlib/manifest.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/stdlib/manifest.rs
+++ b/crates/jrsonnet-evaluator/src/stdlib/manifest.rs
@@ -341,7 +341,7 @@
}
}
}
- Val::Func(_) => throw!(RuntimeError("tried to manifest function".into())),
+ Val::Func(_) => throw!("tried to manifest function"),
}
Ok(())
}
crates/jrsonnet-evaluator/src/typed/conversions.rsdiffbeforeafterboth1use std::ops::Deref;23use jrsonnet_gcmodule::Cc;4use jrsonnet_interner::{IBytes, IStr};5pub use jrsonnet_macros::Typed;6use jrsonnet_types::{ComplexValType, ValType};78use crate::{9 error::{Error::*, Result},10 function::{FuncDesc, FuncVal},11 throw,12 typed::CheckType,13 val::{ArrValue, IndexableVal},14 ObjValue, ObjValueBuilder, State, Val,15};1617pub trait TypedObj: Typed {18 fn serialize(self, s: State, out: &mut ObjValueBuilder) -> Result<()>;19 fn parse(obj: &ObjValue, s: State) -> Result<Self>;20 fn into_object(self, s: State) -> Result<ObjValue> {21 let mut builder = ObjValueBuilder::new();22 self.serialize(s, &mut builder)?;23 Ok(builder.build())24 }25}2627pub trait Typed: Sized {28 const TYPE: &'static ComplexValType;29 fn into_untyped(typed: Self, s: State) -> Result<Val>;30 fn from_untyped(untyped: Val, s: State) -> Result<Self>;31}3233macro_rules! impl_int {34 ($($ty:ty)*) => {$(35 impl Typed for $ty {36 const TYPE: &'static ComplexValType =37 &ComplexValType::BoundedNumber(Some(Self::MIN as f64), Some(Self::MAX as f64));38 fn from_untyped(value: Val, s: State) -> Result<Self> {39 <Self as Typed>::TYPE.check(s, &value)?;40 match value {41 Val::Num(n) => {42 #[allow(clippy::float_cmp)]43 if n.trunc() != n {44 throw!(RuntimeError(45 format!(46 "cannot convert number with fractional part to {}",47 stringify!($ty)48 )49 .into()50 ))51 }52 Ok(n as Self)53 }54 _ => unreachable!(),55 }56 }57 fn into_untyped(value: Self, _: State) -> Result<Val> {58 Ok(Val::Num(value as f64))59 }60 }61 )*};62}6364impl_int!(i8 u8 i16 u16 i32 u32);6566macro_rules! impl_bounded_int {67 ($($name:ident = $ty:ty)*) => {$(68 #[derive(Clone, Copy)]69 pub struct $name<const MIN: $ty, const MAX: $ty>($ty);70 impl<const MIN: $ty, const MAX: $ty> $name<MIN, MAX> {71 pub const fn new(value: $ty) -> Option<$name<MIN, MAX>> {72 if value >= MIN && value <= MAX {73 Some(Self(value))74 } else {75 None76 }77 }78 pub const fn value(self) -> $ty {79 self.080 }81 }82 impl<const MIN: $ty, const MAX: $ty> Deref for $name<MIN, MAX> {83 type Target = $ty;84 fn deref(&self) -> &Self::Target {85 &self.086 }87 }8889 impl<const MIN: $ty, const MAX: $ty> Typed for $name<MIN, MAX> {90 const TYPE: &'static ComplexValType =91 &ComplexValType::BoundedNumber(92 Some(MIN as f64),93 Some(MAX as f64),94 );9596 fn from_untyped(value: Val, s: State) -> Result<Self> {97 <Self as Typed>::TYPE.check(s, &value)?;98 match value {99 Val::Num(n) => {100 #[allow(clippy::float_cmp)]101 if n.trunc() != n {102 throw!(RuntimeError(103 format!(104 "cannot convert number with fractional part to {}",105 stringify!($ty)106 )107 .into()108 ))109 }110 Ok(Self(n as $ty))111 }112 _ => unreachable!(),113 }114 }115116 fn into_untyped(value: Self, _: State) -> Result<Val> {117 Ok(Val::Num(value.0 as f64))118 }119 }120 )*};121}122123impl_bounded_int!(124 BoundedI8 = i8125 BoundedI16 = i16126 BoundedI32 = i32127 BoundedI64 = i64128 BoundedUsize = usize129);130131impl Typed for f64 {132 const TYPE: &'static ComplexValType = &ComplexValType::Simple(ValType::Num);133134 fn into_untyped(value: Self, _: State) -> Result<Val> {135 Ok(Val::Num(value))136 }137138 fn from_untyped(value: Val, s: State) -> Result<Self> {139 <Self as Typed>::TYPE.check(s, &value)?;140 match value {141 Val::Num(n) => Ok(n),142 _ => unreachable!(),143 }144 }145}146147pub struct PositiveF64(pub f64);148impl Typed for PositiveF64 {149 const TYPE: &'static ComplexValType = &ComplexValType::BoundedNumber(Some(0.0), None);150151 fn into_untyped(value: Self, _: State) -> Result<Val> {152 Ok(Val::Num(value.0))153 }154155 fn from_untyped(value: Val, s: State) -> Result<Self> {156 <Self as Typed>::TYPE.check(s, &value)?;157 match value {158 Val::Num(n) => Ok(Self(n)),159 _ => unreachable!(),160 }161 }162}163impl Typed for usize {164 // It is possible to store 54 bits of precision in f64, but leaving u32::MAX here for compatibility165 const TYPE: &'static ComplexValType =166 &ComplexValType::BoundedNumber(Some(0.0), Some(u32::MAX as f64));167168 fn into_untyped(value: Self, _: State) -> Result<Val> {169 if value > u32::MAX as Self {170 throw!(RuntimeError("number is too large".into()))171 }172 Ok(Val::Num(value as f64))173 }174175 fn from_untyped(value: Val, s: State) -> Result<Self> {176 <Self as Typed>::TYPE.check(s, &value)?;177 match value {178 Val::Num(n) => {179 #[allow(clippy::float_cmp)]180 if n.trunc() != n {181 throw!(RuntimeError(182 "cannot convert number with fractional part to usize".into()183 ))184 }185 Ok(n as Self)186 }187 _ => unreachable!(),188 }189 }190}191192impl Typed for IStr {193 const TYPE: &'static ComplexValType = &ComplexValType::Simple(ValType::Str);194195 fn into_untyped(value: Self, _: State) -> Result<Val> {196 Ok(Val::Str(value))197 }198199 fn from_untyped(value: Val, s: State) -> Result<Self> {200 <Self as Typed>::TYPE.check(s, &value)?;201 match value {202 Val::Str(s) => Ok(s),203 _ => unreachable!(),204 }205 }206}207208impl Typed for String {209 const TYPE: &'static ComplexValType = &ComplexValType::Simple(ValType::Str);210211 fn into_untyped(value: Self, _: State) -> Result<Val> {212 Ok(Val::Str(value.into()))213 }214215 fn from_untyped(value: Val, s: State) -> Result<Self> {216 <Self as Typed>::TYPE.check(s, &value)?;217 match value {218 Val::Str(s) => Ok(s.to_string()),219 _ => unreachable!(),220 }221 }222}223224impl Typed for char {225 const TYPE: &'static ComplexValType = &ComplexValType::Char;226227 fn into_untyped(value: Self, _: State) -> Result<Val> {228 Ok(Val::Str(value.to_string().into()))229 }230231 fn from_untyped(value: Val, s: State) -> Result<Self> {232 <Self as Typed>::TYPE.check(s, &value)?;233 match value {234 Val::Str(s) => Ok(s.chars().next().unwrap()),235 _ => unreachable!(),236 }237 }238}239240impl<T> Typed for Vec<T>241where242 T: Typed,243{244 const TYPE: &'static ComplexValType = &ComplexValType::ArrayRef(T::TYPE);245246 fn into_untyped(value: Self, s: State) -> Result<Val> {247 let mut o = Vec::with_capacity(value.len());248 for i in value {249 o.push(T::into_untyped(i, s.clone())?);250 }251 Ok(Val::Arr(o.into()))252 }253254 fn from_untyped(value: Val, s: State) -> Result<Self> {255 <Self as Typed>::TYPE.check(s.clone(), &value)?;256 match value {257 Val::Arr(a) => {258 let mut o = Self::with_capacity(a.len());259 for i in a.iter(s.clone()) {260 o.push(T::from_untyped(i?, s.clone())?);261 }262 Ok(o)263 }264 _ => unreachable!(),265 }266 }267}268269/// To be used in Vec<Any>270/// Regular Val can't be used here, because it has wrong `TryFrom::Error` type271#[derive(Clone)]272pub struct Any(pub Val);273274impl Typed for Any {275 const TYPE: &'static ComplexValType = &ComplexValType::Any;276277 fn into_untyped(value: Self, _: State) -> Result<Val> {278 Ok(value.0)279 }280281 fn from_untyped(value: Val, _: State) -> Result<Self> {282 Ok(Self(value))283 }284}285286/// Specialization, provides faster `TryFrom<VecVal>` for Val287pub struct VecVal(pub Cc<Vec<Val>>);288289impl Typed for VecVal {290 const TYPE: &'static ComplexValType = &ComplexValType::Simple(ValType::Arr);291292 fn into_untyped(value: Self, _: State) -> Result<Val> {293 Ok(Val::Arr(ArrValue::Eager(value.0)))294 }295296 fn from_untyped(value: Val, s: State) -> Result<Self> {297 <Self as Typed>::TYPE.check(s.clone(), &value)?;298 match value {299 Val::Arr(a) => Ok(Self(a.evaluated(s)?)),300 _ => unreachable!(),301 }302 }303}304305/// Specialization306impl Typed for IBytes {307 const TYPE: &'static ComplexValType =308 &ComplexValType::ArrayRef(&ComplexValType::BoundedNumber(Some(0.0), Some(255.0)));309310 fn into_untyped(value: Self, _: State) -> Result<Val> {311 Ok(Val::Arr(ArrValue::Bytes(value)))312 }313314 fn from_untyped(value: Val, s: State) -> Result<Self> {315 if let Val::Arr(ArrValue::Bytes(bytes)) = value {316 return Ok(bytes);317 }318 <Self as Typed>::TYPE.check(s.clone(), &value)?;319 match value {320 Val::Arr(a) => {321 let mut out = Vec::with_capacity(a.len());322 for e in a.iter(s.clone()) {323 let r = e?;324 out.push(u8::from_untyped(r, s.clone())?);325 }326 Ok(out.as_slice().into())327 }328 _ => unreachable!(),329 }330 }331}332333pub struct M1;334impl Typed for M1 {335 const TYPE: &'static ComplexValType = &ComplexValType::BoundedNumber(Some(-1.0), Some(-1.0));336337 fn into_untyped(_: Self, _: State) -> Result<Val> {338 Ok(Val::Num(-1.0))339 }340341 fn from_untyped(value: Val, s: State) -> Result<Self> {342 <Self as Typed>::TYPE.check(s, &value)?;343 Ok(Self)344 }345}346347macro_rules! decl_either {348 ($($name: ident, $($id: ident)*);*) => {$(349 pub enum $name<$($id),*> {350 $($id($id)),*351 }352 impl<$($id),*> Typed for $name<$($id),*>353 where354 $($id: Typed,)*355 {356 const TYPE: &'static ComplexValType = &ComplexValType::UnionRef(&[$($id::TYPE),*]);357358 fn into_untyped(value: Self, s: State) -> Result<Val> {359 match value {$(360 $name::$id(v) => $id::into_untyped(v, s)361 ),*}362 }363364 fn from_untyped(value: Val, s: State) -> Result<Self> {365 $(366 if $id::TYPE.check(s.clone(), &value).is_ok() {367 $id::from_untyped(value, s.clone()).map(Self::$id)368 } else369 )* {370 <Self as Typed>::TYPE.check(s, &value)?;371 unreachable!()372 }373 }374 }375 )*}376}377decl_either!(378 Either1, A;379 Either2, A B;380 Either3, A B C;381 Either4, A B C D;382 Either5, A B C D E;383 Either6, A B C D E F;384 Either7, A B C D E F G385);386#[macro_export]387macro_rules! Either {388 ($a:ty) => {Either1<$a>};389 ($a:ty, $b:ty) => {Either2<$a, $b>};390 ($a:ty, $b:ty, $c:ty) => {Either3<$a, $b, $c>};391 ($a:ty, $b:ty, $c:ty, $d:ty) => {Either4<$a, $b, $c, $d>};392 ($a:ty, $b:ty, $c:ty, $d:ty, $e:ty) => {Either5<$a, $b, $c, $d, $e>};393 ($a:ty, $b:ty, $c:ty, $d:ty, $e:ty, $f:ty) => {Either6<$a, $b, $c, $d, $e, $f>};394 ($a:ty, $b:ty, $c:ty, $d:ty, $e:ty, $f:ty, $g:ty) => {Either7<$a, $b, $c, $d, $e, $f, $g>};395}396pub use Either;397398pub type MyType = Either![u32, f64, String];399400impl Typed for ArrValue {401 const TYPE: &'static ComplexValType = &ComplexValType::Simple(ValType::Arr);402403 fn into_untyped(value: Self, _: State) -> Result<Val> {404 Ok(Val::Arr(value))405 }406407 fn from_untyped(value: Val, s: State) -> Result<Self> {408 <Self as Typed>::TYPE.check(s, &value)?;409 match value {410 Val::Arr(a) => Ok(a),411 _ => unreachable!(),412 }413 }414}415416impl Typed for FuncVal {417 const TYPE: &'static ComplexValType = &ComplexValType::Simple(ValType::Func);418419 fn into_untyped(value: Self, _: State) -> Result<Val> {420 Ok(Val::Func(value))421 }422423 fn from_untyped(value: Val, s: State) -> Result<Self> {424 <Self as Typed>::TYPE.check(s, &value)?;425 match value {426 Val::Func(a) => Ok(a),427 _ => unreachable!(),428 }429 }430}431432impl Typed for Cc<FuncDesc> {433 const TYPE: &'static ComplexValType = &ComplexValType::Simple(ValType::Func);434435 fn into_untyped(value: Self, _: State) -> Result<Val> {436 Ok(Val::Func(FuncVal::Normal(value)))437 }438439 fn from_untyped(value: Val, s: State) -> Result<Self> {440 <Self as Typed>::TYPE.check(s, &value)?;441 match value {442 Val::Func(FuncVal::Normal(desc)) => Ok(desc),443 Val::Func(_) => throw!(RuntimeError("expected normal function, not builtin".into())),444 _ => unreachable!(),445 }446 }447}448449impl Typed for ObjValue {450 const TYPE: &'static ComplexValType = &ComplexValType::Simple(ValType::Obj);451452 fn into_untyped(value: Self, _: State) -> Result<Val> {453 Ok(Val::Obj(value))454 }455456 fn from_untyped(value: Val, s: State) -> Result<Self> {457 <Self as Typed>::TYPE.check(s, &value)?;458 match value {459 Val::Obj(a) => Ok(a),460 _ => unreachable!(),461 }462 }463}464465impl Typed for bool {466 const TYPE: &'static ComplexValType = &ComplexValType::Simple(ValType::Bool);467468 fn into_untyped(value: Self, _: State) -> Result<Val> {469 Ok(Val::Bool(value))470 }471472 fn from_untyped(value: Val, s: State) -> Result<Self> {473 <Self as Typed>::TYPE.check(s, &value)?;474 match value {475 Val::Bool(a) => Ok(a),476 _ => unreachable!(),477 }478 }479}480impl Typed for IndexableVal {481 const TYPE: &'static ComplexValType = &ComplexValType::UnionRef(&[482 &ComplexValType::Simple(ValType::Arr),483 &ComplexValType::Simple(ValType::Str),484 ]);485486 fn into_untyped(value: Self, _: State) -> Result<Val> {487 match value {488 IndexableVal::Str(s) => Ok(Val::Str(s)),489 IndexableVal::Arr(a) => Ok(Val::Arr(a)),490 }491 }492493 fn from_untyped(value: Val, s: State) -> Result<Self> {494 <Self as Typed>::TYPE.check(s, &value)?;495 value.into_indexable()496 }497}498499pub struct Null;500impl Typed for Null {501 const TYPE: &'static ComplexValType = &ComplexValType::Simple(ValType::Null);502503 fn into_untyped(_: Self, _: State) -> Result<Val> {504 Ok(Val::Null)505 }506507 fn from_untyped(value: Val, s: State) -> Result<Self> {508 <Self as Typed>::TYPE.check(s, &value)?;509 Ok(Self)510 }511}1use std::ops::Deref;23use jrsonnet_gcmodule::Cc;4use jrsonnet_interner::{IBytes, IStr};5pub use jrsonnet_macros::Typed;6use jrsonnet_types::{ComplexValType, ValType};78use crate::{9 error::Result,10 function::{FuncDesc, FuncVal},11 throw,12 typed::CheckType,13 val::{ArrValue, IndexableVal},14 ObjValue, ObjValueBuilder, State, Val,15};1617pub trait TypedObj: Typed {18 fn serialize(self, s: State, out: &mut ObjValueBuilder) -> Result<()>;19 fn parse(obj: &ObjValue, s: State) -> Result<Self>;20 fn into_object(self, s: State) -> Result<ObjValue> {21 let mut builder = ObjValueBuilder::new();22 self.serialize(s, &mut builder)?;23 Ok(builder.build())24 }25}2627pub trait Typed: Sized {28 const TYPE: &'static ComplexValType;29 fn into_untyped(typed: Self, s: State) -> Result<Val>;30 fn from_untyped(untyped: Val, s: State) -> Result<Self>;31}3233macro_rules! impl_int {34 ($($ty:ty)*) => {$(35 impl Typed for $ty {36 const TYPE: &'static ComplexValType =37 &ComplexValType::BoundedNumber(Some(Self::MIN as f64), Some(Self::MAX as f64));38 fn from_untyped(value: Val, s: State) -> Result<Self> {39 <Self as Typed>::TYPE.check(s, &value)?;40 match value {41 Val::Num(n) => {42 #[allow(clippy::float_cmp)]43 if n.trunc() != n {44 throw!(45 "cannot convert number with fractional part to {}",46 stringify!($ty)47 )48 }49 Ok(n as Self)50 }51 _ => unreachable!(),52 }53 }54 fn into_untyped(value: Self, _: State) -> Result<Val> {55 Ok(Val::Num(value as f64))56 }57 }58 )*};59}6061impl_int!(i8 u8 i16 u16 i32 u32);6263macro_rules! impl_bounded_int {64 ($($name:ident = $ty:ty)*) => {$(65 #[derive(Clone, Copy)]66 pub struct $name<const MIN: $ty, const MAX: $ty>($ty);67 impl<const MIN: $ty, const MAX: $ty> $name<MIN, MAX> {68 pub const fn new(value: $ty) -> Option<$name<MIN, MAX>> {69 if value >= MIN && value <= MAX {70 Some(Self(value))71 } else {72 None73 }74 }75 pub const fn value(self) -> $ty {76 self.077 }78 }79 impl<const MIN: $ty, const MAX: $ty> Deref for $name<MIN, MAX> {80 type Target = $ty;81 fn deref(&self) -> &Self::Target {82 &self.083 }84 }8586 impl<const MIN: $ty, const MAX: $ty> Typed for $name<MIN, MAX> {87 const TYPE: &'static ComplexValType =88 &ComplexValType::BoundedNumber(89 Some(MIN as f64),90 Some(MAX as f64),91 );9293 fn from_untyped(value: Val, s: State) -> Result<Self> {94 <Self as Typed>::TYPE.check(s, &value)?;95 match value {96 Val::Num(n) => {97 #[allow(clippy::float_cmp)]98 if n.trunc() != n {99 throw!(100 "cannot convert number with fractional part to {}",101 stringify!($ty)102 )103 }104 Ok(Self(n as $ty))105 }106 _ => unreachable!(),107 }108 }109110 fn into_untyped(value: Self, _: State) -> Result<Val> {111 Ok(Val::Num(value.0 as f64))112 }113 }114 )*};115}116117impl_bounded_int!(118 BoundedI8 = i8119 BoundedI16 = i16120 BoundedI32 = i32121 BoundedI64 = i64122 BoundedUsize = usize123);124125impl Typed for f64 {126 const TYPE: &'static ComplexValType = &ComplexValType::Simple(ValType::Num);127128 fn into_untyped(value: Self, _: State) -> Result<Val> {129 Ok(Val::Num(value))130 }131132 fn from_untyped(value: Val, s: State) -> Result<Self> {133 <Self as Typed>::TYPE.check(s, &value)?;134 match value {135 Val::Num(n) => Ok(n),136 _ => unreachable!(),137 }138 }139}140141pub struct PositiveF64(pub f64);142impl Typed for PositiveF64 {143 const TYPE: &'static ComplexValType = &ComplexValType::BoundedNumber(Some(0.0), None);144145 fn into_untyped(value: Self, _: State) -> Result<Val> {146 Ok(Val::Num(value.0))147 }148149 fn from_untyped(value: Val, s: State) -> Result<Self> {150 <Self as Typed>::TYPE.check(s, &value)?;151 match value {152 Val::Num(n) => Ok(Self(n)),153 _ => unreachable!(),154 }155 }156}157impl Typed for usize {158 // It is possible to store 54 bits of precision in f64, but leaving u32::MAX here for compatibility159 const TYPE: &'static ComplexValType =160 &ComplexValType::BoundedNumber(Some(0.0), Some(u32::MAX as f64));161162 fn into_untyped(value: Self, _: State) -> Result<Val> {163 if value > u32::MAX as Self {164 throw!("number is too large")165 }166 Ok(Val::Num(value as f64))167 }168169 fn from_untyped(value: Val, s: State) -> Result<Self> {170 <Self as Typed>::TYPE.check(s, &value)?;171 match value {172 Val::Num(n) => {173 #[allow(clippy::float_cmp)]174 if n.trunc() != n {175 throw!("cannot convert number with fractional part to usize")176 }177 Ok(n as Self)178 }179 _ => unreachable!(),180 }181 }182}183184impl Typed for IStr {185 const TYPE: &'static ComplexValType = &ComplexValType::Simple(ValType::Str);186187 fn into_untyped(value: Self, _: State) -> Result<Val> {188 Ok(Val::Str(value))189 }190191 fn from_untyped(value: Val, s: State) -> Result<Self> {192 <Self as Typed>::TYPE.check(s, &value)?;193 match value {194 Val::Str(s) => Ok(s),195 _ => unreachable!(),196 }197 }198}199200impl Typed for String {201 const TYPE: &'static ComplexValType = &ComplexValType::Simple(ValType::Str);202203 fn into_untyped(value: Self, _: State) -> Result<Val> {204 Ok(Val::Str(value.into()))205 }206207 fn from_untyped(value: Val, s: State) -> Result<Self> {208 <Self as Typed>::TYPE.check(s, &value)?;209 match value {210 Val::Str(s) => Ok(s.to_string()),211 _ => unreachable!(),212 }213 }214}215216impl Typed for char {217 const TYPE: &'static ComplexValType = &ComplexValType::Char;218219 fn into_untyped(value: Self, _: State) -> Result<Val> {220 Ok(Val::Str(value.to_string().into()))221 }222223 fn from_untyped(value: Val, s: State) -> Result<Self> {224 <Self as Typed>::TYPE.check(s, &value)?;225 match value {226 Val::Str(s) => Ok(s.chars().next().unwrap()),227 _ => unreachable!(),228 }229 }230}231232impl<T> Typed for Vec<T>233where234 T: Typed,235{236 const TYPE: &'static ComplexValType = &ComplexValType::ArrayRef(T::TYPE);237238 fn into_untyped(value: Self, s: State) -> Result<Val> {239 let mut o = Vec::with_capacity(value.len());240 for i in value {241 o.push(T::into_untyped(i, s.clone())?);242 }243 Ok(Val::Arr(o.into()))244 }245246 fn from_untyped(value: Val, s: State) -> Result<Self> {247 <Self as Typed>::TYPE.check(s.clone(), &value)?;248 match value {249 Val::Arr(a) => {250 let mut o = Self::with_capacity(a.len());251 for i in a.iter(s.clone()) {252 o.push(T::from_untyped(i?, s.clone())?);253 }254 Ok(o)255 }256 _ => unreachable!(),257 }258 }259}260261/// To be used in Vec<Any>262/// Regular Val can't be used here, because it has wrong `TryFrom::Error` type263#[derive(Clone)]264pub struct Any(pub Val);265266impl Typed for Any {267 const TYPE: &'static ComplexValType = &ComplexValType::Any;268269 fn into_untyped(value: Self, _: State) -> Result<Val> {270 Ok(value.0)271 }272273 fn from_untyped(value: Val, _: State) -> Result<Self> {274 Ok(Self(value))275 }276}277278/// Specialization, provides faster `TryFrom<VecVal>` for Val279pub struct VecVal(pub Cc<Vec<Val>>);280281impl Typed for VecVal {282 const TYPE: &'static ComplexValType = &ComplexValType::Simple(ValType::Arr);283284 fn into_untyped(value: Self, _: State) -> Result<Val> {285 Ok(Val::Arr(ArrValue::Eager(value.0)))286 }287288 fn from_untyped(value: Val, s: State) -> Result<Self> {289 <Self as Typed>::TYPE.check(s.clone(), &value)?;290 match value {291 Val::Arr(a) => Ok(Self(a.evaluated(s)?)),292 _ => unreachable!(),293 }294 }295}296297/// Specialization298impl Typed for IBytes {299 const TYPE: &'static ComplexValType =300 &ComplexValType::ArrayRef(&ComplexValType::BoundedNumber(Some(0.0), Some(255.0)));301302 fn into_untyped(value: Self, _: State) -> Result<Val> {303 Ok(Val::Arr(ArrValue::Bytes(value)))304 }305306 fn from_untyped(value: Val, s: State) -> Result<Self> {307 if let Val::Arr(ArrValue::Bytes(bytes)) = value {308 return Ok(bytes);309 }310 <Self as Typed>::TYPE.check(s.clone(), &value)?;311 match value {312 Val::Arr(a) => {313 let mut out = Vec::with_capacity(a.len());314 for e in a.iter(s.clone()) {315 let r = e?;316 out.push(u8::from_untyped(r, s.clone())?);317 }318 Ok(out.as_slice().into())319 }320 _ => unreachable!(),321 }322 }323}324325pub struct M1;326impl Typed for M1 {327 const TYPE: &'static ComplexValType = &ComplexValType::BoundedNumber(Some(-1.0), Some(-1.0));328329 fn into_untyped(_: Self, _: State) -> Result<Val> {330 Ok(Val::Num(-1.0))331 }332333 fn from_untyped(value: Val, s: State) -> Result<Self> {334 <Self as Typed>::TYPE.check(s, &value)?;335 Ok(Self)336 }337}338339macro_rules! decl_either {340 ($($name: ident, $($id: ident)*);*) => {$(341 pub enum $name<$($id),*> {342 $($id($id)),*343 }344 impl<$($id),*> Typed for $name<$($id),*>345 where346 $($id: Typed,)*347 {348 const TYPE: &'static ComplexValType = &ComplexValType::UnionRef(&[$($id::TYPE),*]);349350 fn into_untyped(value: Self, s: State) -> Result<Val> {351 match value {$(352 $name::$id(v) => $id::into_untyped(v, s)353 ),*}354 }355356 fn from_untyped(value: Val, s: State) -> Result<Self> {357 $(358 if $id::TYPE.check(s.clone(), &value).is_ok() {359 $id::from_untyped(value, s.clone()).map(Self::$id)360 } else361 )* {362 <Self as Typed>::TYPE.check(s, &value)?;363 unreachable!()364 }365 }366 }367 )*}368}369decl_either!(370 Either1, A;371 Either2, A B;372 Either3, A B C;373 Either4, A B C D;374 Either5, A B C D E;375 Either6, A B C D E F;376 Either7, A B C D E F G377);378#[macro_export]379macro_rules! Either {380 ($a:ty) => {Either1<$a>};381 ($a:ty, $b:ty) => {Either2<$a, $b>};382 ($a:ty, $b:ty, $c:ty) => {Either3<$a, $b, $c>};383 ($a:ty, $b:ty, $c:ty, $d:ty) => {Either4<$a, $b, $c, $d>};384 ($a:ty, $b:ty, $c:ty, $d:ty, $e:ty) => {Either5<$a, $b, $c, $d, $e>};385 ($a:ty, $b:ty, $c:ty, $d:ty, $e:ty, $f:ty) => {Either6<$a, $b, $c, $d, $e, $f>};386 ($a:ty, $b:ty, $c:ty, $d:ty, $e:ty, $f:ty, $g:ty) => {Either7<$a, $b, $c, $d, $e, $f, $g>};387}388pub use Either;389390pub type MyType = Either![u32, f64, String];391392impl Typed for ArrValue {393 const TYPE: &'static ComplexValType = &ComplexValType::Simple(ValType::Arr);394395 fn into_untyped(value: Self, _: State) -> Result<Val> {396 Ok(Val::Arr(value))397 }398399 fn from_untyped(value: Val, s: State) -> Result<Self> {400 <Self as Typed>::TYPE.check(s, &value)?;401 match value {402 Val::Arr(a) => Ok(a),403 _ => unreachable!(),404 }405 }406}407408impl Typed for FuncVal {409 const TYPE: &'static ComplexValType = &ComplexValType::Simple(ValType::Func);410411 fn into_untyped(value: Self, _: State) -> Result<Val> {412 Ok(Val::Func(value))413 }414415 fn from_untyped(value: Val, s: State) -> Result<Self> {416 <Self as Typed>::TYPE.check(s, &value)?;417 match value {418 Val::Func(a) => Ok(a),419 _ => unreachable!(),420 }421 }422}423424impl Typed for Cc<FuncDesc> {425 const TYPE: &'static ComplexValType = &ComplexValType::Simple(ValType::Func);426427 fn into_untyped(value: Self, _: State) -> Result<Val> {428 Ok(Val::Func(FuncVal::Normal(value)))429 }430431 fn from_untyped(value: Val, s: State) -> Result<Self> {432 <Self as Typed>::TYPE.check(s, &value)?;433 match value {434 Val::Func(FuncVal::Normal(desc)) => Ok(desc),435 Val::Func(_) => throw!("expected normal function, not builtin"),436 _ => unreachable!(),437 }438 }439}440441impl Typed for ObjValue {442 const TYPE: &'static ComplexValType = &ComplexValType::Simple(ValType::Obj);443444 fn into_untyped(value: Self, _: State) -> Result<Val> {445 Ok(Val::Obj(value))446 }447448 fn from_untyped(value: Val, s: State) -> Result<Self> {449 <Self as Typed>::TYPE.check(s, &value)?;450 match value {451 Val::Obj(a) => Ok(a),452 _ => unreachable!(),453 }454 }455}456457impl Typed for bool {458 const TYPE: &'static ComplexValType = &ComplexValType::Simple(ValType::Bool);459460 fn into_untyped(value: Self, _: State) -> Result<Val> {461 Ok(Val::Bool(value))462 }463464 fn from_untyped(value: Val, s: State) -> Result<Self> {465 <Self as Typed>::TYPE.check(s, &value)?;466 match value {467 Val::Bool(a) => Ok(a),468 _ => unreachable!(),469 }470 }471}472impl Typed for IndexableVal {473 const TYPE: &'static ComplexValType = &ComplexValType::UnionRef(&[474 &ComplexValType::Simple(ValType::Arr),475 &ComplexValType::Simple(ValType::Str),476 ]);477478 fn into_untyped(value: Self, _: State) -> Result<Val> {479 match value {480 IndexableVal::Str(s) => Ok(Val::Str(s)),481 IndexableVal::Arr(a) => Ok(Val::Arr(a)),482 }483 }484485 fn from_untyped(value: Val, s: State) -> Result<Self> {486 <Self as Typed>::TYPE.check(s, &value)?;487 value.into_indexable()488 }489}490491pub struct Null;492impl Typed for Null {493 const TYPE: &'static ComplexValType = &ComplexValType::Simple(ValType::Null);494495 fn into_untyped(_: Self, _: State) -> Result<Val> {496 Ok(Val::Null)497 }498499 fn from_untyped(value: Val, s: State) -> Result<Self> {500 <Self as Typed>::TYPE.check(s, &value)?;501 Ok(Self)502 }503}crates/jrsonnet-evaluator/src/val.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/val.rs
+++ b/crates/jrsonnet-evaluator/src/val.rs
@@ -629,7 +629,7 @@
if num.is_finite() {
Ok(Self::Num(num))
} else {
- throw!(RuntimeError("overflow".into()))
+ throw!("overflow")
}
}
@@ -843,14 +843,14 @@
(Val::Null, Val::Null) => true,
(Val::Str(a), Val::Str(b)) => a == b,
(Val::Num(a), Val::Num(b)) => (a - b).abs() <= f64::EPSILON,
- (Val::Arr(_), Val::Arr(_)) => throw!(RuntimeError(
- "primitiveEquals operates on primitive types, got array".into(),
- )),
- (Val::Obj(_), Val::Obj(_)) => throw!(RuntimeError(
- "primitiveEquals operates on primitive types, got object".into(),
- )),
+ (Val::Arr(_), Val::Arr(_)) => {
+ throw!("primitiveEquals operates on primitive types, got array")
+ }
+ (Val::Obj(_), Val::Obj(_)) => {
+ throw!("primitiveEquals operates on primitive types, got object")
+ }
(a, b) if is_function_like(a) && is_function_like(b) => {
- throw!(RuntimeError("cannot test equality of functions".into()))
+ throw!("cannot test equality of functions")
}
(_, _) => false,
})
crates/jrsonnet-stdlib/src/arrays.rsdiffbeforeafterboth--- a/crates/jrsonnet-stdlib/src/arrays.rs
+++ b/crates/jrsonnet-stdlib/src/arrays.rs
@@ -1,7 +1,7 @@
use jrsonnet_evaluator::{
error::Result,
function::{builtin, FuncVal},
- throw_runtime,
+ throw,
typed::{Any, BoundedUsize, Typed, VecVal},
val::{equals, ArrValue, IndexableVal},
IStr, State, Val,
@@ -43,7 +43,7 @@
match func.evaluate_simple(s.clone(), &(c.to_string(),))? {
Val::Str(o) => out.push_str(&o),
Val::Null => continue,
- _ => throw_runtime!("in std.join all items should be strings"),
+ _ => throw!("in std.join all items should be strings"),
};
}
Ok(IndexableVal::Str(out.into()))
@@ -59,7 +59,7 @@
}
}
Val::Null => continue,
- _ => throw_runtime!("in std.join all items should be arrays"),
+ _ => throw!("in std.join all items should be arrays"),
};
}
Ok(IndexableVal::Arr(out.into()))
@@ -128,7 +128,7 @@
} else if matches!(item, Val::Null) {
continue;
} else {
- throw_runtime!("in std.join all items should be arrays");
+ throw!("in std.join all items should be arrays");
}
}
@@ -149,7 +149,7 @@
} else if matches!(item, Val::Null) {
continue;
} else {
- throw_runtime!("in std.join all items should be strings");
+ throw!("in std.join all items should be strings");
}
}
crates/jrsonnet-stdlib/src/lib.rsdiffbeforeafterboth--- a/crates/jrsonnet-stdlib/src/lib.rs
+++ b/crates/jrsonnet-stdlib/src/lib.rs
@@ -8,7 +8,7 @@
error::{Error::*, Result},
function::{builtin::Builtin, ArgLike, CallLocation, FuncVal, TlaArg},
gc::{GcHashMap, TraceBox},
- tb, throw_runtime,
+ tb, throw,
trace::PathResolver,
typed::{Any, Either, Either2, Either4, VecVal, M1},
val::{equals, ArrValue},
@@ -500,7 +500,7 @@
true
}
}
- _ => throw_runtime!("both arguments should be of the same type"),
+ _ => throw!("both arguments should be of the same type"),
})
}
@@ -534,7 +534,7 @@
true
}
}
- _ => throw_runtime!("both arguments should be of the same type"),
+ _ => throw!("both arguments should be of the same type"),
})
}
crates/jrsonnet-stdlib/src/sort.rsdiffbeforeafterboth--- a/crates/jrsonnet-stdlib/src/sort.rs
+++ b/crates/jrsonnet-stdlib/src/sort.rs
@@ -1,7 +1,7 @@
use jrsonnet_evaluator::{
error::Result,
function::{builtin, FuncVal},
- throw_runtime,
+ throw,
typed::Any,
val::ArrValue,
State, Val,
@@ -41,9 +41,9 @@
(Val::Num(_), SortKeyType::Unknown) => sort_type = SortKeyType::Number,
(Val::Str(_), SortKeyType::String) | (Val::Num(_), SortKeyType::Number) => {}
(Val::Str(_) | Val::Num(_), _) => {
- throw_runtime!("sort elements should have the same types")
+ throw!("sort elements should have the same types")
}
- _ => throw_runtime!("sort key should either be a string or a number"),
+ _ => throw!("sort key should either be a string or a number"),
}
}
Ok(sort_type)
tests/tests/common.rsdiffbeforeafterboth--- a/tests/tests/common.rs
+++ b/tests/tests/common.rs
@@ -1,7 +1,7 @@
use jrsonnet_evaluator::{
error::Result,
function::{builtin, FuncVal},
- throw_runtime, ObjValueBuilder, State, Thunk, Val,
+ throw, ObjValueBuilder, State, Thunk, Val,
};
use jrsonnet_stdlib::StateExt;
@@ -11,7 +11,7 @@
let a = &$a;
let b = &$b;
if a != b {
- ::jrsonnet_evaluator::throw_runtime!("assertion failed: a != b\na={:#?}\nb={:#?}", a, b)
+ ::jrsonnet_evaluator::throw!("assertion failed: a != b\na={:#?}\nb={:#?}", a, b)
}
}};
}
@@ -20,7 +20,7 @@
macro_rules! ensure {
($v:expr $(,)?) => {
if !$v {
- ::jrsonnet_evaluator::throw_runtime!("assertion failed: {}", stringify!($v))
+ ::jrsonnet_evaluator::throw!("assertion failed: {}", stringify!($v))
}
};
}
@@ -29,7 +29,7 @@
macro_rules! ensure_val_eq {
($s:expr, $a:expr, $b:expr) => {{
if !::jrsonnet_evaluator::val::equals($s.clone(), &$a.clone(), &$b.clone())? {
- ::jrsonnet_evaluator::throw_runtime!(
+ ::jrsonnet_evaluator::throw!(
"assertion failed: a != b\na={:#?}\nb={:#?}",
$a.to_json(
$s.clone(),
@@ -52,7 +52,7 @@
fn assert_throw(s: State, lazy: Thunk<Val>, message: String) -> Result<bool> {
match lazy.evaluate(s) {
Ok(_) => {
- throw_runtime!("expected argument to throw on evaluation, but it returned instead")
+ throw!("expected argument to throw on evaluation, but it returned instead")
}
Err(e) => {
let error = format!("{}", e.error());
tests/tests/sanity.rsdiffbeforeafterboth--- a/tests/tests/sanity.rs
+++ b/tests/tests/sanity.rs
@@ -1,4 +1,4 @@
-use jrsonnet_evaluator::{error::Result, throw_runtime, State, Val};
+use jrsonnet_evaluator::{error::Result, throw, State, Val};
use jrsonnet_stdlib::StateExt;
mod common;
@@ -23,7 +23,7 @@
{
let e = match s.evaluate_snippet("snip".to_owned(), "assert 1 == 2: 'fail'; null") {
- Ok(_) => throw_runtime!("assertion should fail"),
+ Ok(_) => throw!("assertion should fail"),
Err(e) => e,
};
let e = s.stringify_err(&e);
@@ -31,7 +31,7 @@
}
{
let e = match s.evaluate_snippet("snip".to_owned(), "std.assertEqual(1, 2)") {
- Ok(_) => throw_runtime!("assertion should fail"),
+ Ok(_) => throw!("assertion should fail"),
Err(e) => e,
};
let e = s.stringify_err(&e);