luajit_bindings/
error.rs

1use std::ffi::c_int;
2
3use thiserror::Error as ThisError;
4
5use crate::utils;
6
7#[derive(Clone, Debug, Eq, PartialEq, ThisError, Hash)]
8pub enum Error {
9    #[error(
10        "Value of type {ty} couldn't be popped from the stack{}.",
11        message.as_ref().map(|msg| format!(": {msg}")).unwrap_or_default()
12    )]
13    PopError { ty: &'static str, message: Option<String> },
14
15    #[error(
16        "Value of type {ty} couldn't be pushed on the stack{}.",
17        message.as_ref().map(|msg| format!(": {msg}")).unwrap_or_default()
18    )]
19    PushError { ty: &'static str, message: Option<String> },
20
21    #[error("Lua runtime error: {0}")]
22    RuntimeError(String),
23
24    #[error("Lua memory error: {0}")]
25    MemoryError(String),
26
27    #[error("TODO")]
28    PopEmptyStack,
29}
30
31impl Error {
32    pub fn pop_error<M: Into<String>>(ty: &'static str, message: M) -> Self {
33        Self::PopError { ty, message: Some(message.into()) }
34    }
35
36    pub fn pop_error_from_err<T, E: std::error::Error>(err: E) -> Self {
37        Self::PopError {
38            ty: std::any::type_name::<T>(),
39            message: Some(err.to_string()),
40        }
41    }
42
43    pub fn pop_wrong_type<T>(expected: c_int, found: c_int) -> Self {
44        let ty = std::any::type_name::<T>();
45        let expected = utils::type_name(expected);
46        let found = utils::type_name(found);
47        Self::PopError {
48            ty,
49            message: Some(format!(
50                "expected a {}, found a {} instead",
51                expected, found
52            )),
53        }
54    }
55
56    pub unsafe fn pop_wrong_type_at_idx<T>(
57        lstate: *mut crate::ffi::lua_State,
58        idx: std::ffi::c_int,
59    ) -> Self {
60        let expected = std::any::type_name::<T>();
61        let got = crate::utils::debug_type(lstate, idx);
62
63        Self::PopError {
64            ty: expected,
65            message: Some(format!(
66                "expected {}, got {} instead",
67                expected, got
68            )),
69        }
70    }
71
72    pub fn push_error<M: Into<String>>(ty: &'static str, message: M) -> Self {
73        Self::PushError { ty, message: Some(message.into()) }
74    }
75
76    pub fn push_error_from_err<T, E: std::error::Error>(err: E) -> Self {
77        Self::PushError {
78            ty: std::any::type_name::<T>(),
79            message: Some(err.to_string()),
80        }
81    }
82}