c_ares/
error.rs

1use std::error;
2use std::fmt;
3use std::os::raw::c_int;
4use std::result;
5
6use crate::utils::c_string_as_str_unchecked;
7
8/// Error codes that the library might return.
9#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash, PartialOrd, Ord)]
10pub enum Error {
11    /// DNS server returned answer with no data.
12    ENODATA = c_ares_sys::ares_status_t::ARES_ENODATA as isize,
13
14    /// DNS server claims query was misformatted.
15    EFORMERR = c_ares_sys::ares_status_t::ARES_EFORMERR as isize,
16
17    /// DNS server returned general failure.
18    ESERVFAIL = c_ares_sys::ares_status_t::ARES_ESERVFAIL as isize,
19
20    /// Domain name not found.
21    ENOTFOUND = c_ares_sys::ares_status_t::ARES_ENOTFOUND as isize,
22
23    /// DNS server does not implement requested operation.
24    ENOTIMP = c_ares_sys::ares_status_t::ARES_ENOTIMP as isize,
25
26    /// DNS server refused query.
27    EREFUSED = c_ares_sys::ares_status_t::ARES_EREFUSED as isize,
28
29    /// Misformatted DNS query.
30    EBADQUERY = c_ares_sys::ares_status_t::ARES_EBADQUERY as isize,
31
32    /// Misformatted domain name.
33    EBADNAME = c_ares_sys::ares_status_t::ARES_EBADNAME as isize,
34
35    /// Unsupported address family.
36    EBADFAMILY = c_ares_sys::ares_status_t::ARES_EBADFAMILY as isize,
37
38    /// Misformatted DNS reply.
39    EBADRESP = c_ares_sys::ares_status_t::ARES_EBADRESP as isize,
40
41    /// Could not contact DNS servers.
42    ECONNREFUSED = c_ares_sys::ares_status_t::ARES_ECONNREFUSED as isize,
43
44    /// Timeout while contacting DNS servers.
45    ETIMEOUT = c_ares_sys::ares_status_t::ARES_ETIMEOUT as isize,
46
47    /// End of file.
48    EOF = c_ares_sys::ares_status_t::ARES_EOF as isize,
49
50    /// Error reading file.
51    EFILE = c_ares_sys::ares_status_t::ARES_EFILE as isize,
52
53    /// Out of memory.
54    ENOMEM = c_ares_sys::ares_status_t::ARES_ENOMEM as isize,
55
56    /// Channel is being destroyed.
57    EDESTRUCTION = c_ares_sys::ares_status_t::ARES_EDESTRUCTION as isize,
58
59    /// Misformatted string.
60    EBADSTR = c_ares_sys::ares_status_t::ARES_EBADSTR as isize,
61
62    /// Illegal flags specified.
63    EBADFLAGS = c_ares_sys::ares_status_t::ARES_EBADFLAGS as isize,
64
65    /// Given hostname is not numeric.
66    ENONAME = c_ares_sys::ares_status_t::ARES_ENONAME as isize,
67
68    /// Illegal hints flags specified.
69    EBADHINTS = c_ares_sys::ares_status_t::ARES_EBADHINTS as isize,
70
71    /// c-ares library initialization not yet performed.
72    ENOTINITIALIZED = c_ares_sys::ares_status_t::ARES_ENOTINITIALIZED as isize,
73
74    /// Error loading iphlpapi.dll.
75    ELOADIPHLPAPI = c_ares_sys::ares_status_t::ARES_ELOADIPHLPAPI as isize,
76
77    /// Could not find GetNetworkParams function.
78    EADDRGETNETWORKPARAMS = c_ares_sys::ares_status_t::ARES_EADDRGETNETWORKPARAMS as isize,
79
80    /// DNS query cancelled.
81    ECANCELLED = c_ares_sys::ares_status_t::ARES_ECANCELLED as isize,
82
83    /// The textual service name provided could not be dereferenced into a port.
84    ESERVICE = c_ares_sys::ares_status_t::ARES_ESERVICE as isize,
85
86    /// No DNS servers were configured.
87    ENOSERVER = c_ares_sys::ares_status_t::ARES_ENOSERVER as isize,
88
89    /// Unknown error.
90    UNKNOWN,
91}
92
93impl error::Error for Error {}
94
95impl fmt::Display for Error {
96    fn fmt(&self, fmt: &mut fmt::Formatter) -> result::Result<(), fmt::Error> {
97        let text = unsafe {
98            let ptr = c_ares_sys::ares_strerror(*self as c_int);
99            c_string_as_str_unchecked(ptr)
100        };
101        fmt.write_str(text)
102    }
103}
104
105impl From<i32> for Error {
106    fn from(code: i32) -> Self {
107        match code {
108            x if x == Error::ENODATA as i32 => Error::ENODATA,
109            x if x == Error::EFORMERR as i32 => Error::EFORMERR,
110            x if x == Error::ESERVFAIL as i32 => Error::ESERVFAIL,
111            x if x == Error::ENOTFOUND as i32 => Error::ENOTFOUND,
112            x if x == Error::ENOTIMP as i32 => Error::ENOTIMP,
113            x if x == Error::EREFUSED as i32 => Error::EREFUSED,
114            x if x == Error::EBADQUERY as i32 => Error::EBADQUERY,
115            x if x == Error::EBADNAME as i32 => Error::EBADNAME,
116            x if x == Error::EBADFAMILY as i32 => Error::EBADFAMILY,
117            x if x == Error::EBADRESP as i32 => Error::EBADRESP,
118            x if x == Error::ECONNREFUSED as i32 => Error::ECONNREFUSED,
119            x if x == Error::ETIMEOUT as i32 => Error::ETIMEOUT,
120            x if x == Error::EOF as i32 => Error::EOF,
121            x if x == Error::EFILE as i32 => Error::EFILE,
122            x if x == Error::ENOMEM as i32 => Error::ENOMEM,
123            x if x == Error::EDESTRUCTION as i32 => Error::EDESTRUCTION,
124            x if x == Error::EBADSTR as i32 => Error::EBADSTR,
125            x if x == Error::EBADFLAGS as i32 => Error::EBADFLAGS,
126            x if x == Error::ENONAME as i32 => Error::ENONAME,
127            x if x == Error::EBADHINTS as i32 => Error::EBADHINTS,
128            x if x == Error::ENOTINITIALIZED as i32 => Error::ENOTINITIALIZED,
129            x if x == Error::ELOADIPHLPAPI as i32 => Error::ELOADIPHLPAPI,
130            x if x == Error::EADDRGETNETWORKPARAMS as i32 => Error::EADDRGETNETWORKPARAMS,
131            x if x == Error::ECANCELLED as i32 => Error::ECANCELLED,
132            x if x == Error::ESERVICE as i32 => Error::ESERVICE,
133            x if x == Error::ENOSERVER as i32 => Error::ENOSERVER,
134            _ => Error::UNKNOWN,
135        }
136    }
137}
138
139impl TryFrom<c_ares_sys::ares_status_t> for Error {
140    type Error = ();
141
142    fn try_from(
143        status: c_ares_sys::ares_status_t,
144    ) -> std::result::Result<Self, <Self as TryFrom<c_ares_sys::ares_status_t>>::Error> {
145        let error = match status {
146            c_ares_sys::ares_status_t::ARES_SUCCESS => return Err(()),
147            c_ares_sys::ares_status_t::ARES_ENODATA => Error::ENODATA,
148            c_ares_sys::ares_status_t::ARES_EFORMERR => Error::EFORMERR,
149            c_ares_sys::ares_status_t::ARES_ESERVFAIL => Error::ESERVFAIL,
150            c_ares_sys::ares_status_t::ARES_ENOTFOUND => Error::ENOTFOUND,
151            c_ares_sys::ares_status_t::ARES_ENOTIMP => Error::ENOTIMP,
152            c_ares_sys::ares_status_t::ARES_EREFUSED => Error::EREFUSED,
153            c_ares_sys::ares_status_t::ARES_EBADQUERY => Error::EBADQUERY,
154            c_ares_sys::ares_status_t::ARES_EBADNAME => Error::EBADNAME,
155            c_ares_sys::ares_status_t::ARES_EBADFAMILY => Error::EBADFAMILY,
156            c_ares_sys::ares_status_t::ARES_EBADRESP => Error::EBADRESP,
157            c_ares_sys::ares_status_t::ARES_ECONNREFUSED => Error::ECONNREFUSED,
158            c_ares_sys::ares_status_t::ARES_ETIMEOUT => Error::ETIMEOUT,
159            c_ares_sys::ares_status_t::ARES_EOF => Error::EOF,
160            c_ares_sys::ares_status_t::ARES_EFILE => Error::EFILE,
161            c_ares_sys::ares_status_t::ARES_ENOMEM => Error::ENOMEM,
162            c_ares_sys::ares_status_t::ARES_EDESTRUCTION => Error::EDESTRUCTION,
163            c_ares_sys::ares_status_t::ARES_EBADSTR => Error::EBADSTR,
164            c_ares_sys::ares_status_t::ARES_EBADFLAGS => Error::EBADFLAGS,
165            c_ares_sys::ares_status_t::ARES_ENONAME => Error::ENONAME,
166            c_ares_sys::ares_status_t::ARES_EBADHINTS => Error::EBADHINTS,
167            c_ares_sys::ares_status_t::ARES_ENOTINITIALIZED => Error::ENOTINITIALIZED,
168            c_ares_sys::ares_status_t::ARES_ELOADIPHLPAPI => Error::ELOADIPHLPAPI,
169            c_ares_sys::ares_status_t::ARES_EADDRGETNETWORKPARAMS => Error::EADDRGETNETWORKPARAMS,
170            c_ares_sys::ares_status_t::ARES_ECANCELLED => Error::ECANCELLED,
171            c_ares_sys::ares_status_t::ARES_ESERVICE => Error::ESERVICE,
172            c_ares_sys::ares_status_t::ARES_ENOSERVER => Error::ENOSERVER,
173        };
174        Ok(error)
175    }
176}
177
178/// The type used by this library for methods that might fail.
179pub type Result<T> = result::Result<T, Error>;