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 with_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 #[cfg(target_family = "windows")]
71 pub fn doserrno() -> Error {
72 Error::new(doserrno())
73 }
74
75 pub fn msg(&self) -> &str {
76 &self.errmsg
77 }
78
79 pub fn num(&self) -> i32 {
80 self.errnum
81 }
82}
83
84impl error::Error for Error {
85 fn source(&self) -> Option<&(dyn error::Error + 'static)> {
86 self.source.error_ref()
87 }
88}
89
90impl fmt::Debug for Error {
91 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
92 match &self.source {
93 Source::FromVecWithNulError(e) => <FromVecWithNulError as fmt::Debug>::fmt(e, f),
94 Source::NulError(e) => <NulError as fmt::Debug>::fmt(e, f),
95 Source::None => write!(f, "Error {{ errmsg: \"{}\", errnum: {} }}",
96 self.errmsg, self.errnum)
97 }
98 }
99}
100
101impl fmt::Display for Error {
102 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
103 match &self.source {
104 Source::FromVecWithNulError(e) => write!(f, "Error: {}", e),
105 Source::NulError(e) => write!(f, "Error: {}", e),
106 Source::None => write!(f, "Error {}: {}", self.errnum, self.errmsg)
107 }
108 }
109}
110
111impl From<FromVecWithNulError> for Error {
112 fn from(value: FromVecWithNulError) -> Self {
113 Error {
114 errmsg: String::from("Interior NUL byte"),
115 errnum: 0,
116 source: Source::FromVecWithNulError(value)
117 }
118 }
119}
120
121impl From<NulError> for Error {
122 fn from(value: NulError) -> Self {
123 Error {
124 errmsg: String::from("Interior NUL byte"),
125 errnum: 0,
126 source: Source::NulError(value)
127 }
128 }
129}
130
131impl cmp::Eq for Error { }
132
133impl cmp::PartialEq for Error {
134 fn eq(&self, other: &Self) -> bool {
135 self.errnum == other.errnum
136 }
137}