1use std::ffi::FromVecWithNulError;
28use std::ffi::NulError;
29use std::{cmp,fmt};
30use std::{error,result};
31
32mod source;
33use crate::errno::source::Source;
34use crate::string::strerror;
35
36#[cfg(target_family = "unix")]
37#[doc(inline)]
38pub use crate::posix::errno::*;
39
40#[cfg(target_family = "windows")]
41#[doc(inline)]
42pub use crate::windows::errno::*;
43
44pub type Result<T> = result::Result<T, Error>;
45
46pub struct Error {
47 errmsg: String,
48 errnum: i32,
49 source: Source
50}
51
52impl Error {
53 pub fn new(errnum: i32) -> Error {
54 let source = Source::None;
55 match strerror(errnum) {
56 Ok(errmsg) => Error { errmsg, errnum, source },
57 Err(err) => err
58 }
59 }
60
61 pub fn new_msg(errnum: i32, errmsg: String) -> Error {
62 let source = Source::None;
63 Error { errmsg, errnum, source }
64 }
65
66 pub fn errno() -> Error {
67 Error::new(errno())
68 }
69
70 pub fn msg(&self) -> &str {
71 &self.errmsg
72 }
73
74 pub fn num(&self) -> i32 {
75 self.errnum
76 }
77}
78
79impl error::Error for Error {
80 fn source(&self) -> Option<&(dyn error::Error + 'static)> {
81 self.source.error_ref()
82 }
83}
84
85impl fmt::Debug for Error {
86 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
87 match &self.source {
88 Source::FromVecWithNulError(e) => <FromVecWithNulError as fmt::Debug>::fmt(e, f),
89 Source::NulError(e) => <NulError as fmt::Debug>::fmt(e, f),
90 Source::None => write!(f, "Error {{ errmsg: \"{}\", errnum: {} }}",
91 self.errmsg, self.errnum)
92 }
93 }
94}
95
96impl fmt::Display for Error {
97 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
98 match &self.source {
99 Source::FromVecWithNulError(e) => write!(f, "Error: {}", e),
100 Source::NulError(e) => write!(f, "Error: {}", e),
101 Source::None => write!(f, "Error {}: {}", self.errnum, self.errmsg)
102 }
103 }
104}
105
106impl From<FromVecWithNulError> for Error {
107 fn from(value: FromVecWithNulError) -> Self {
108 Error {
109 errmsg: String::from("Interior NUL byte"),
110 errnum: 0,
111 source: Source::FromVecWithNulError(value)
112 }
113 }
114}
115
116impl From<NulError> for Error {
117 fn from(value: NulError) -> Self {
118 Error {
119 errmsg: String::from("Interior NUL byte"),
120 errnum: 0,
121 source: Source::NulError(value)
122 }
123 }
124}
125
126impl cmp::Eq for Error { }
127
128impl cmp::PartialEq for Error {
129 fn eq(&self, other: &Self) -> bool {
130 self.errnum == other.errnum
131 }
132}