1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
use std::fmt;
use std::result::Result;
use std::error::Error;
use std::ffi::NulError;
use std::cell::{BorrowError, BorrowMutError};
use std::str::Utf8Error;

#[derive(Debug)]
pub struct LuaExternalError(pub Box<Error + Send>);

impl fmt::Display for LuaExternalError {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        self.0.fmt(fmt)
    }
}

impl Error for LuaExternalError {
    fn description(&self) -> &str {
        self.0.description()
    }

    fn cause(&self) -> Option<&Error> {
        self.0.cause()
    }
}

error_chain! {
    types {
        LuaError, LuaErrorKind, LuaResultExt, LuaResult;
    }

    errors {
        ScriptError(err: String) {
            display("Error executing lua script {}", err)
        }
        CallbackError(err: String) {
            display("Error during lua callback {}", err)
        }
        IncompleteStatement(err: String) {
            display("Incomplete lua statement {}", err)
        }
        CoroutineInactive {
            display("Cannot resume inactive coroutine")
        }
    }

    foreign_links {
        ExternalError(LuaExternalError);
        Utf8Error(Utf8Error);
        NulError(NulError);
        BorrowError(BorrowError);
        BorrowMutError(BorrowMutError);
    }
}

/// Helper trait to convert external error types to a `LuaExternalError`
pub trait LuaExternalResult<T> {
    fn to_lua_err(self) -> LuaResult<T>;
}

impl<T, E> LuaExternalResult<T> for Result<T, E>
where
    E: 'static + Error + Send,
{
    fn to_lua_err(self) -> LuaResult<T> {
        self.map_err(|e| LuaExternalError(Box::new(e)).into())
    }
}