1use crate::status::LuaStatus;
4use crate::value::LuaValue;
5use std::fmt;
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10pub struct LuaExit(pub i32);
11
12#[derive(Debug, Clone, Copy, PartialEq, Eq)]
16pub struct LuaThreadClose(pub LuaStatus);
17
18#[derive(Debug, Clone)]
21pub enum LuaError {
22 Runtime(LuaValue),
23 Syntax(LuaValue),
24 Memory,
25 Error,
26 Yield,
27 File,
28 Gc,
29}
30
31impl LuaError {
32 pub fn runtime(args: fmt::Arguments<'_>) -> Self {
34 LuaError::Runtime(LuaValue::Str(crate::gc::GcRef::new(
35 crate::string::LuaString::from_bytes(format!("{}", args).into_bytes()),
36 )))
37 }
38 pub fn syntax(args: fmt::Arguments<'_>) -> Self {
39 LuaError::Syntax(LuaValue::Str(crate::gc::GcRef::new(
40 crate::string::LuaString::from_bytes(format!("{}", args).into_bytes()),
41 )))
42 }
43 pub fn syntax_at(args: fmt::Arguments<'_>, source: &[u8], line: i32) -> Self {
44 LuaError::Syntax(LuaValue::Str(crate::gc::GcRef::new(
45 crate::string::LuaString::from_bytes(
46 format!("{}:{}: {}", String::from_utf8_lossy(source), line, args).into_bytes(),
47 ),
48 )))
49 }
50 pub fn syntax_raw(msg: &[u8]) -> Self {
51 LuaError::Syntax(LuaValue::Str(crate::gc::GcRef::new(
52 crate::string::LuaString::from_bytes(msg.to_vec()),
53 )))
54 }
55
56 pub fn type_error(v: &LuaValue, op: &str) -> Self {
58 LuaError::runtime(format_args!("attempt to {} a {} value", op, v.type_name()))
59 }
60 pub fn call_error(v: &LuaValue) -> Self {
61 Self::type_error(v, "call")
62 }
63 pub fn concat_error(p1: &LuaValue, p2: &LuaValue) -> Self {
64 let bad = if matches!(p1, LuaValue::Str(_) | LuaValue::Int(_) | LuaValue::Float(_)) {
65 p2
66 } else {
67 p1
68 };
69 LuaError::runtime(format_args!(
70 "attempt to concatenate a {} value",
71 bad.type_name()
72 ))
73 }
74 pub fn arith_error(p1: &LuaValue, p2: &LuaValue, _msg: &str) -> Self {
75 let bad = if matches!(p1, LuaValue::Int(_) | LuaValue::Float(_)) {
76 p2
77 } else {
78 p1
79 };
80 LuaError::runtime(format_args!(
81 "attempt to perform arithmetic on a {} value",
82 bad.type_name()
83 ))
84 }
85 pub fn int_overflow(_p1: &LuaValue, _p2: &LuaValue) -> Self {
86 LuaError::runtime(format_args!("number has no integer representation"))
87 }
88 pub fn order_error(p1: &LuaValue, p2: &LuaValue) -> Self {
89 LuaError::runtime(format_args!(
90 "attempt to compare {} with {}",
91 p1.type_name(),
92 p2.type_name()
93 ))
94 }
95 pub fn for_error(v: &LuaValue, what: &str) -> Self {
96 LuaError::runtime(format_args!(
97 "bad 'for' {} (number expected, got {})",
98 what,
99 v.type_name()
100 ))
101 }
102 pub fn arg_error(narg: i32, msg: &str) -> Self {
103 LuaError::runtime(format_args!("bad argument #{} ({})", narg, msg))
104 }
105 pub fn type_arg_error(narg: i32, expected: &str, got: &LuaValue) -> Self {
106 LuaError::runtime(format_args!(
107 "bad argument #{} ({} expected, got {})",
108 narg,
109 expected,
110 got.type_name()
111 ))
112 }
113
114 pub fn from_value(v: LuaValue) -> Self {
116 LuaError::Runtime(v)
119 }
120 pub fn with_status(status: LuaStatus) -> Self {
121 match status {
122 LuaStatus::Ok => LuaError::Error,
123 LuaStatus::Yield => LuaError::Yield,
124 LuaStatus::ErrRun => LuaError::Runtime(LuaValue::Nil),
125 LuaStatus::ErrSyntax => LuaError::Syntax(LuaValue::Nil),
126 LuaStatus::ErrMem => LuaError::Memory,
127 LuaStatus::ErrErr => LuaError::Error,
128 LuaStatus::ErrFile => LuaError::File,
129 LuaStatus::ErrGc => LuaError::Gc,
130 }
131 }
132
133 pub fn to_status(&self) -> LuaStatus {
134 match self {
135 LuaError::Runtime(_) => LuaStatus::ErrRun,
136 LuaError::Syntax(_) => LuaStatus::ErrSyntax,
137 LuaError::Memory => LuaStatus::ErrMem,
138 LuaError::Error => LuaStatus::ErrErr,
139 LuaError::Yield => LuaStatus::Yield,
140 LuaError::File => LuaStatus::ErrFile,
141 LuaError::Gc => LuaStatus::ErrGc,
142 }
143 }
144
145 pub fn into_value(self) -> LuaValue {
146 match self {
147 LuaError::Runtime(v) | LuaError::Syntax(v) => v,
148 _ => LuaValue::Nil,
149 }
150 }
151}
152
153impl fmt::Display for LuaError {
154 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
155 write!(f, "{:?}", self)
156 }
157}
158impl std::error::Error for LuaError {}
159
160