safe_libc/errno/
mod.rs

1//
2// Created:  Thu 16 Apr 2020 01:19:12 PM PDT
3// Modified: Fri 21 Nov 2025 01:17:44 PM PST
4//
5// Copyright (C) 2020 Robert Gill <rtgill82@gmail.com>
6//
7// Permission is hereby granted, free of charge, to any person obtaining a copy
8// of this software and associated documentation files (the "Software"), to
9// deal in the Software without restriction, including without limitation the
10// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
11// sell copies of the Software, and to permit persons to whom the Software is
12// furnished to do so, subject to the following conditions:
13//
14// The above copyright notice and this permission notice shall be included in
15// all copies of the Software, its documentation and marketing & publicity
16// materials, and acknowledgment shall be given in the documentation, materials
17// and software packages that this Software was used.
18//
19// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22// THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
23// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25//
26
27use 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}