mrubyedge/
error.rs

1use std::error;
2use std::fmt;
3use std::rc::Rc;
4
5use crate::yamrb::value::RClass;
6use crate::yamrb::value::RObject;
7use crate::yamrb::vm::VM;
8
9#[derive(Debug, Clone, PartialEq)]
10pub enum Error {
11    General,
12    Internal(String),
13    InvalidOpCode,
14    RuntimeError(String),
15    ArgumentError(String),
16    TypeMismatch,
17    NoMethodError(String),
18    NameError(String),
19
20    Break(Rc<RObject>),
21    BlockReturn(usize, Rc<RObject>),
22}
23
24impl fmt::Display for Error {
25    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
26        write!(f, "error nr {:?}", self)
27    }
28}
29
30impl error::Error for Error {}
31
32impl Error {
33    pub fn internal(msg: impl Into<String>) -> Error {
34        Error::Internal(msg.into())
35    }
36
37    pub fn message(&self) -> String {
38        match self {
39            Error::General => "General error".to_string(),
40            Error::Internal(msg) => format!("[Internal Error] {}", msg.clone()),
41            Error::InvalidOpCode => "Invalid opcode".to_string(),
42            Error::RuntimeError(msg) => msg.clone(),
43            Error::ArgumentError(msg) => format!("Invalid argument: {}", msg),
44            Error::TypeMismatch => "Type mismatch".to_string(),
45            Error::NoMethodError(msg) => format!("Method not found: {}", msg),
46            Error::NameError(msg) => format!("Cannot found name: {}", msg),
47
48            Error::Break(_) => "[Break]".to_string(),
49            Error::BlockReturn(_, _) => "[BlockReturn]".to_string(),
50        }
51    }
52
53    pub fn is_instance_of(&self, other: Rc<RClass>) -> bool {
54        matches!(
55            (self, other.sym_id.name.as_str()),
56            (Error::General, "StandardError")
57                | (Error::Internal(_), "InternalError")
58                | (Error::InvalidOpCode, "StandardError")
59                | (Error::RuntimeError(_), "RuntimeError")
60                | (Error::ArgumentError(_), "ArgumentError")
61                | (Error::TypeMismatch, "StandardError")
62                | (Error::NoMethodError(_), "NoMethodError")
63                | (Error::NameError(_), "NameError")
64        )
65    }
66
67    pub fn is_a(&self, vm: &mut VM, other: Rc<RClass>) -> bool {
68        let mut klass: Option<Rc<RClass>> = RClass::from_error(vm, self).into();
69        let target_klass_name = other.sym_id.name.as_str();
70
71        while let Some(k) = klass {
72            if k.sym_id.name.as_str() == target_klass_name {
73                return true;
74            }
75            klass = k.super_class.clone();
76        }
77        false
78    }
79}
80
81/// Used for asynchronous or multithreaded context
82#[derive(Debug, Clone, PartialEq)]
83pub enum StaticError {
84    General(String),
85}
86
87impl fmt::Display for StaticError {
88    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
89        write!(f, "error nr {:?}", self)
90    }
91}
92
93impl error::Error for StaticError {}
94
95unsafe impl Sync for StaticError {}
96unsafe impl Send for StaticError {}
97
98impl From<Error> for StaticError {
99    fn from(err: Error) -> StaticError {
100        match err {
101            Error::General => StaticError::General("General error".to_string()),
102            Error::Internal(msg) => StaticError::General(format!("[Internal Error] {}", msg)),
103            Error::InvalidOpCode => StaticError::General("Invalid opcode".to_string()),
104            Error::RuntimeError(msg) => StaticError::General(msg),
105            Error::ArgumentError(msg) => StaticError::General(format!("Invalid argument: {}", msg)),
106            Error::TypeMismatch => StaticError::General("Type mismatch".to_string()),
107            Error::NoMethodError(msg) => StaticError::General(format!("Method not found: {}", msg)),
108            Error::NameError(msg) => StaticError::General(format!("Cannot found name: {}", msg)),
109
110            Error::Break(_) => StaticError::General("[Break]".to_string()),
111            Error::BlockReturn(_, _) => StaticError::General("[BlockReturn]".to_string()),
112        }
113    }
114}