1use std::borrow::Cow;
2use std::ffi::CStr;
3
4#[derive(Clone, Copy, Default, PartialEq, Eq)]
6pub struct SysError(i32);
7
8impl std::fmt::Display for SysError {
9 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
10 write!(f, "{}", self.to_str())
11 }
12}
13
14impl std::fmt::Debug for SysError {
15 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
16 write!(
17 f,
18 r#"SysError {{ Code={}, Reason={:?} }}"#,
19 self.0,
20 self.to_str()
21 )
22 }
23}
24
25impl std::error::Error for SysError {}
26
27impl From<i32> for SysError {
28 fn from(val: i32) -> Self {
29 Self { 0: val }
30 }
31}
32
33impl Into<i32> for SysError {
34 fn into(self) -> i32 {
35 self.0
36 }
37}
38
39impl SysError {
40 #[cfg(unix)]
42 pub fn last() -> Self {
43 unsafe {
44 Self {
45 0: *(libc::__errno_location()),
46 }
47 }
48 }
49
50 pub fn is_err(self) -> bool {
52 self.0 != 0
53 }
54
55 pub fn is_ok(self) -> bool {
57 !self.is_err()
58 }
59
60 pub fn map_or<T>(self, other: T) -> Result<T, SysError> {
62 if self.is_err() {
63 Err(self)
64 } else {
65 Ok(other)
66 }
67 }
68
69 #[cfg(unix)]
71 pub fn to_str(&self) -> Cow<str> {
72 unsafe { CStr::from_ptr(libc::strerror(self.0)).to_string_lossy() }
73 }
74}
75
76#[cfg(test)]
77mod tests {
78 use super::*;
79
80 #[test]
81 fn test_sys_error() {
82 let err = SysError::last();
83 assert_eq!(err.is_err(), false);
84 }
85}