1use std::fmt;
13
14#[derive(Debug, Clone, PartialEq, Eq)]
16pub enum CoreError {
17 Syscall {
19 code: i32,
21 op: &'static str,
23 },
24}
25
26impl CoreError {
27 pub fn sys(code: i32, op: &'static str) -> Self {
29 Self::Syscall { code, op }
30 }
31
32 pub fn raw_os_error(&self) -> Option<i32> {
34 match self {
35 Self::Syscall { code, .. } => Some(*code),
36 }
37 }
38
39 pub fn to_io_error(&self) -> std::io::Error {
41 std::io::Error::from_raw_os_error(self.raw_os_error().unwrap_or(libc::EIO))
42 }
43}
44
45impl fmt::Display for CoreError {
46 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
47 match self {
48 Self::Syscall { code, op } => write!(f, "{op} failed (code={code})"),
49 }
50 }
51}
52
53impl std::error::Error for CoreError {}
54
55#[inline(always)]
56pub(crate) fn syscall_ret(ret: i32, op: &'static str) -> Result<(), CoreError> {
57 if ret == -1 {
58 let code = std::io::Error::last_os_error().raw_os_error().unwrap_or(0);
59 Err(CoreError::sys(code, op))
60 } else {
61 Ok(())
62 }
63}
64
65#[inline(always)]
66pub(crate) fn posix_ret(ret: i32, op: &'static str) -> Result<(), CoreError> {
67 if ret != 0 {
68 Err(CoreError::sys(ret, op))
69 } else {
70 Ok(())
71 }
72}