use crate::utils::*;
use alloc::string::String;
use emlite::{FromJsError, Val};
macro_rules! declare_error {
($base:ident $(, $name:ident)*) => {
#[derive(Clone, Debug, PartialEq, PartialOrd)]
#[repr(transparent)]
pub struct $base { inner: emlite::Val }
bind!($base);
impl_dyn_cast!($base);
impl $base {
pub fn new(msg: &str) -> Self {
emlite::Val::global(stringify!($base))
.new(&[msg.into()])
.as_::<Self>()
}
pub fn message(&self) -> Option<String> { self.inner.get("message").as_() }
pub fn name(&self) -> Option<String> { self.inner.get("name").as_() }
pub fn stack(&self) -> Option<String> {
let s = self.inner.get("stack");
if s.is_undefined() { None } else { s.as_() }
}
}
impl core::fmt::Display for $base {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{:?}: {:?}", self.name(), self.message())
}
}
impl core::error::Error for $base {}
impl FromJsError for $base {
fn from_js_error(val: &Val) -> Self {
val.as_::<Self>()
}
}
$(
#[derive(Clone, Debug, PartialEq, PartialOrd)]
#[repr(transparent)]
pub struct $name { inner: emlite::Val }
bind!($name);
impl_dyn_cast!($name);
impl $name {
pub fn new(msg: &str) -> Self {
emlite::Val::global(stringify!($name))
.new(&[msg.into()])
.as_::<Self>()
}
pub fn message(&self) -> Option<String> { <$base>::from(self.clone()).message() }
pub fn name(&self) -> Option<String> { <$base>::from(self.clone()).name() }
pub fn stack(&self) -> Option<String>{ <$base>::from(self.clone()).stack() }
}
impl core::fmt::Display for $name {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{:?}: {:?}", self.name(), self.message())
}
}
impl core::error::Error for $name {}
impl From<$name> for $base {
fn from(e: $name) -> $base { e.inner.clone().as_::<$base>() }
}
impl FromJsError for $name {
fn from_js_error(val: &Val) -> Self {
val.as_::<Self>()
}
}
)*
};
}
declare_error!(
JsError,
EvalError,
RangeError,
ReferenceError,
SyntaxError,
TypeError,
URIError,
AggregateError
);