1
//! Error types.
2

            
3
use thiserror::Error;
4

            
5
use crate::ffi;
6

            
7
/// Wraps all error types returned by `minion_rs`.
8
#[derive(Debug, Error)]
9
#[non_exhaustive]
10
pub enum MinionError {
11
    /// An error has occurred during the execution of Minion.
12
    #[error("runtime error: `{0}.to_string()`")]
13
    RuntimeError(#[from] RuntimeError),
14

            
15
    /// The input model uses Minion features that are not yet implemented in `minion_rs`.
16
    #[error("not implemented: {0}")]
17
    NotImplemented(String),
18

            
19
    /// Catch-all error.
20
    #[error(transparent)]
21
    Other(#[from] anyhow::Error), // source and Display delegate to anyhow::Error
22
}
23

            
24
/// Errors thrown by Minion during execution.
25
///
26
/// These represent internal Minion C++ exceptions translated into Rust.
27
///
28
/// Invalid usage of this library should throw an error before Minion is even run. Therefore, these
29
/// should be quite rare. Consider creating an issue on
30
/// [Github](https://github.com/conjure-cp/conjure-oxide) if these occur regularly!
31
#[derive(Debug, Error, Eq, PartialEq)]
32
#[non_exhaustive]
33
pub enum RuntimeError {
34
    // These closely follow the ReturnCodes found in Minion's libwrapper.cpp.
35
    /// The model given to Minion is invalid.
36
    #[error("the given instance is invalid")]
37
    InvalidInstance,
38

            
39
    /// An unknown error has occurred.
40
    #[error("an unknown error has occurred while running minion")]
41
    UnknownError,
42
}
43

            
44
// Minion's ReturnCodes are passed over FFI as ints.
45
// Convert them to their appropriate error.
46
impl From<u32> for RuntimeError {
47
    fn from(return_code: u32) -> Self {
48
        match return_code {
49
            #[allow(non_upper_case_globals)]
50
            ffi::ReturnCodes_INVALID_INSTANCE => RuntimeError::InvalidInstance,
51
            _ => RuntimeError::UnknownError,
52
        }
53
    }
54
}