use cljrs_value::Value;
use cljrs_value::ValueError;
#[derive(Debug, thiserror::Error)]
pub enum EvalError {
#[error("runtime error: {0}")]
Runtime(String),
#[error("gas exhausted")]
GasExhausted,
#[error("effect forbidden in transaction function: {0}")]
ForbiddenEffect(String),
#[error("unbound symbol: {0}")]
UnboundSymbol(String),
#[error("arity error calling {name}: expected {expected}, got {got}")]
Arity {
name: String,
expected: String,
got: usize,
},
#[error("not callable: {0}")]
NotCallable(String),
#[error("{0}")]
Thrown(Value),
#[error("read error: {0}")]
Read(#[from] cljrs_types::error::CljxError),
#[doc(hidden)]
#[error("internal: recur outside loop or fn")]
Recur(Vec<Value>),
#[error(
"commit {commit:?} failed signature verification — \
refusing to execute versioned symbol (enable GPG/SSH trust or disable \
:verify-commit-signatures): {reason}"
)]
CommitSignatureVerificationFailed { commit: String, reason: String },
}
impl EvalError {
pub fn to_error_value(self) -> Value {
match self {
EvalError::Thrown(v) => v,
other => {
let msg = other.to_string();
Value::Error(cljrs_gc::GcPtr::new(cljrs_value::ExceptionInfo::new(
cljrs_value::ValueError::Other(msg.clone()),
msg,
None,
None,
)))
}
}
}
}
pub fn value_error_to_eval_error(err: ValueError) -> EvalError {
match err {
ValueError::Thrown(v) => EvalError::Thrown(v),
ValueError::GasExhausted => EvalError::GasExhausted,
other => {
let msg = other.to_string();
EvalError::Thrown(Value::Error(cljrs_gc::GcPtr::new(
cljrs_value::ExceptionInfo::new(other, msg, None, None),
)))
}
}
}
pub type EvalResult<T = Value> = Result<T, EvalError>;