1use iree_embedded_sys as sys;
8
9const CODE_MASK: usize = 0x1F;
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq)]
13pub enum StatusCode {
14 Aborted,
16 OutOfMemory,
18 NotFound,
20 InvalidArgument,
22 Unimplemented,
24 Internal,
26 Unknown,
28}
29
30const MSG_CAP: usize = 192;
31
32#[derive(Clone, Copy)]
35pub struct Error {
36 code: StatusCode,
37 raw: u32,
38 msg: [u8; MSG_CAP],
39 msg_len: usize,
40}
41
42impl Error {
43 pub fn code(&self) -> StatusCode {
45 self.code
46 }
47
48 pub fn raw_code(&self) -> u32 {
50 self.raw
51 }
52
53 pub fn message(&self) -> &str {
55 core::str::from_utf8(&self.msg[..self.msg_len]).unwrap_or("<non-utf8>")
56 }
57}
58
59impl core::fmt::Debug for Error {
60 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
61 write!(
62 f,
63 "Error({:?}, raw={}, {})",
64 self.code,
65 self.raw,
66 self.message()
67 )
68 }
69}
70
71pub type Result<T> = core::result::Result<T, Error>;
73
74pub(crate) fn check(status: sys::iree_status_t) -> Result<()> {
77 if status.is_null() {
78 return Ok(());
79 }
80 let code = (status as usize & CODE_MASK) as u32;
81 let mut msg = [0u8; MSG_CAP];
82 let mut len: sys::iree_host_size_t = 0;
83 unsafe {
85 sys::iree_status_format(status, msg.len(), msg.as_mut_ptr() as *mut _, &mut len);
86 sys::iree_status_free(status);
87 }
88 Err(Error {
89 code: map(code),
90 raw: code,
91 msg,
92 msg_len: (len as usize).min(MSG_CAP),
93 })
94}
95
96fn map(code: u32) -> StatusCode {
97 use StatusCode::*;
98 match code {
99 sys::IREE_STATUS_ABORTED => Aborted,
100 sys::IREE_STATUS_RESOURCE_EXHAUSTED => OutOfMemory,
101 sys::IREE_STATUS_NOT_FOUND => NotFound,
102 sys::IREE_STATUS_INVALID_ARGUMENT => InvalidArgument,
103 sys::IREE_STATUS_UNIMPLEMENTED => Unimplemented,
104 sys::IREE_STATUS_INTERNAL => Internal,
105 _ => Unknown,
106 }
107}
108
109#[cfg(test)]
110mod tests {
111 use super::*;
112
113 fn status_of(code: u32) -> sys::iree_status_t {
115 code as usize as sys::iree_status_t
116 }
117
118 #[test]
119 fn ok_status_is_ok() {
120 assert!(check(core::ptr::null_mut()).is_ok());
121 }
122
123 #[test]
124 fn aborted_maps_to_error() {
125 let st = status_of(sys::IREE_STATUS_ABORTED);
126 assert_eq!(check(st).unwrap_err().code(), StatusCode::Aborted);
127 }
128
129 #[test]
130 fn resource_exhausted_maps_to_oom() {
131 let st = status_of(sys::IREE_STATUS_RESOURCE_EXHAUSTED);
132 assert_eq!(check(st).unwrap_err().code(), StatusCode::OutOfMemory);
133 }
134}