1use std::{any::Any, error::Error, fmt::Debug};
2
3#[cfg(feature = "sys")]
4use crate::BackendException;
5use crate::{Exception, RuntimeError, macros::backend::match_rt};
6
7#[derive(Debug, derive_more::From)]
9pub enum BackendTrap {
10 #[cfg(feature = "sys")]
11 Sys(crate::backend::sys::vm::Trap),
13
14 #[cfg(feature = "v8")]
15 V8(crate::backend::v8::vm::Trap),
17
18 #[cfg(feature = "js")]
19 Js(crate::backend::js::vm::Trap),
21}
22
23impl BackendTrap {
24 pub fn user(err: Box<dyn Error + Send + Sync>) -> RuntimeError {
28 #[cfg(feature = "sys")]
29 {
30 return crate::backend::sys::vm::Trap::user(err).into();
31 }
32
33 #[cfg(feature = "v8")]
34 {
35 return crate::backend::v8::vm::Trap::user(err).into();
36 }
37 #[cfg(feature = "js")]
38 {
39 return crate::backend::js::vm::Trap::user(err).into();
40 }
41
42 panic!("No runtime enabled!")
43 }
44 #[inline]
46 pub fn downcast<T: Error + 'static>(self) -> Result<T, Self> {
47 match_rt!(on self => s {
48 s.downcast::<T>().map_err(Into::into)
49 })
50 }
51
52 #[inline]
54 pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> {
55 match_rt!(on self => s {
56 s.downcast_ref::<T>()
57 })
58 }
59
60 #[inline]
62 pub fn is<T: Error + 'static>(&self) -> bool {
63 match_rt!(on self => s {
64 s.is::<T>()
65 })
66 }
67
68 #[inline]
70 pub fn is_exception(&self) -> bool {
71 match_rt!(on self => s {
72 s.is_exception()
73 })
74 }
75
76 #[inline]
78 pub fn to_exception(&self) -> Option<Exception> {
79 match self {
80 #[cfg(feature = "sys")]
81 Self::Sys(s) => s
82 .to_exception_ref()
83 .map(|e| Exception::from_vm_exceptionref(crate::vm::VMExceptionRef::Sys(e))),
84 #[cfg(feature = "v8")]
85 Self::V8(s) => s
86 .to_exception_ref()
87 .map(|e| Exception::from_vm_exceptionref(crate::vm::VMExceptionRef::V8(e))),
88 #[cfg(feature = "js")]
89 Self::Js(s) => s
90 .to_exception_ref()
91 .map(|e| Exception::from_vm_exceptionref(crate::vm::VMExceptionRef::Js(e))),
92 }
93 }
94}
95
96impl std::fmt::Display for BackendTrap {
97 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
98 match_rt!(on self => s {
99 (s as &dyn std::fmt::Display).fmt(f)
100 })
101 }
102}
103
104impl std::error::Error for BackendTrap {
105 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
106 match_rt!(on self => s {
107 s.source()
108 })
109 }
110}