1use thiserror::Error;
4
5use crate::ffi;
6
7#[derive(Debug, Error)]
9#[non_exhaustive]
10pub enum MinionError {
11 #[error("runtime error: `{0}.to_string()`")]
13 RuntimeError(#[from] RuntimeError),
14
15 #[error("not implemented: {0}")]
17 NotImplemented(String),
18
19 #[error(transparent)]
21 Other(#[from] anyhow::Error), }
23
24#[derive(Debug, Error, Eq, PartialEq)]
32#[non_exhaustive]
33pub enum RuntimeError {
34 #[error("the given instance is invalid: {0}")]
37 InvalidInstance(String),
38
39 #[error("solver timed out")]
41 Timeout,
42
43 #[error("solver ran out of memory")]
45 MemoryError,
46
47 #[error("parse error: {0}")]
49 ParseError(String),
50
51 #[error("invalid argument: {0}")]
53 InvalidArgument(String),
54
55 #[error("an unknown error has occurred while running minion: {0}")]
57 UnknownError(String),
58}
59
60pub fn check_minion_result(code: u32) -> Result<(), RuntimeError> {
64 #[allow(non_upper_case_globals)]
65 match code {
66 ffi::MinionResult_MINION_OK => Ok(()),
67 _ => {
68 let msg = unsafe {
69 let p = ffi::minion_error_message();
70 if p.is_null() {
71 String::new()
72 } else {
73 std::ffi::CStr::from_ptr(p).to_string_lossy().into_owned()
74 }
75 };
76 Err(match code {
77 ffi::MinionResult_MINION_INVALID_INSTANCE => RuntimeError::InvalidInstance(msg),
78 ffi::MinionResult_MINION_TIMEOUT => RuntimeError::Timeout,
79 ffi::MinionResult_MINION_MEMORY_ERROR => RuntimeError::MemoryError,
80 ffi::MinionResult_MINION_PARSE_ERROR => RuntimeError::ParseError(msg),
81 ffi::MinionResult_MINION_INVALID_ARGUMENT => RuntimeError::InvalidArgument(msg),
82 _ => RuntimeError::UnknownError(msg),
83 })
84 }
85 }
86}