nvim_oxi_luajit/
error.rs

1use core::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 {expected}, found a {found} instead",
51            )),
52        }
53    }
54
55    pub unsafe fn pop_wrong_type_at_idx<T>(
56        lstate: *mut crate::ffi::State,
57        idx: std::ffi::c_int,
58    ) -> Self {
59        let expected = std::any::type_name::<T>();
60        let got = crate::utils::debug_type(lstate, idx);
61
62        Self::PopError {
63            ty: expected,
64            message: Some(format!("expected {expected}, got {got} instead",)),
65        }
66    }
67
68    pub fn push_error<M: Into<String>>(ty: &'static str, message: M) -> Self {
69        Self::PushError { ty, message: Some(message.into()) }
70    }
71
72    pub fn push_error_from_err<T, E: std::error::Error>(err: E) -> Self {
73        Self::PushError {
74            ty: std::any::type_name::<T>(),
75            message: Some(err.to_string()),
76        }
77    }
78}