Skip to main content

pavo_common/
sys_error.rs

1use std::borrow::Cow;
2use std::ffi::CStr;
3
4/// 定义系统错误。
5#[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    /// 从系统当前 errno 创建一个 SysError 对象。
41    #[cfg(unix)]
42    pub fn last() -> Self {
43        unsafe {
44            Self {
45                0: *(libc::__errno_location()),
46            }
47        }
48    }
49
50    /// 检测是否为出错状态。
51    pub fn is_err(self) -> bool {
52        self.0 != 0
53    }
54
55    /// 检测是否为无错状态。
56    pub fn is_ok(self) -> bool {
57        !self.is_err()
58    }
59
60    /// 当无错时将返回值映射为其他值。
61    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    /// 返回文本描述。
70    #[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}