1use std::{
2 error,
3 fmt,
4 io,
5};
6
7use crate::ffi;
8
9pub enum Error {
11 KnownError(ffi::DNSServiceError),
13 UnknownError(i32),
15 IoError(io::Error),
17}
18
19impl Error {
20 pub fn from(value: ffi::DNSServiceErrorType) -> Result<(), Self> {
24 if ffi::DNSServiceNoError::try_from(value).is_some() {
25 Ok(())
26 } else {
27 match ffi::DNSServiceError::try_from(value) {
28 Some(e) => Err(Self::KnownError(e)),
29 None => Err(Self::UnknownError(value)),
30 }
31 }
32 }
33}
34
35impl From<io::Error> for Error {
36 fn from(e: io::Error) -> Self {
37 Self::IoError(e)
38 }
39}
40
41impl From<Error> for io::Error {
42 fn from(e: Error) -> Self {
43 match e {
44 Error::IoError(e) => e,
45 e => Self::other(e),
46 }
47 }
48}
49
50impl fmt::Debug for Error {
51 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
52 match self {
53 Self::KnownError(ffi_err) => write!(f, "known error {:?}: {}", ffi_err, ffi_err),
54 Self::UnknownError(e) => write!(f, "unknown error code: {:?}", e),
55 Self::IoError(e) => write!(f, "io error: {:?}", e),
56 }
57 }
58}
59impl fmt::Display for Error {
60 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
61 match self {
62 Self::KnownError(ffi_err) => write!(f, "{}", ffi_err),
63 Self::UnknownError(e) => write!(f, "unknown error code: {:?}", e),
64 Self::IoError(e) => write!(f, "io error: {}", e),
65 }
66 }
67}
68impl error::Error for Error {
69 fn source(&self) -> Option<&(dyn error::Error + 'static)> {
70 match self {
71 Self::KnownError(ffi_err) => Some(ffi_err),
72 Self::UnknownError(_) => None,
73 Self::IoError(e) => Some(e),
74 }
75 }
76}
77
78impl ffi::DNSServiceError {
79 pub fn description(&self) -> &str {
80 use ffi::DNSServiceError::*;
81 match *self {
82 Unknown => "unknown error",
83 NoSuchName => "no such name",
84 NoMemory => "out of memory",
85 BadParam => "bad parameter",
86 BadReference => "bad reference",
87 BadState => "bad state",
88 BadFlags => "bad flags",
89 Unsupported => "not supported",
90 NotInitialized => "not initialized",
91 AlreadyRegistered => "already registered",
93 NameConflict => "name conflict",
94 Invalid => "invalid",
95 Firewall => "firewall",
96 Incompatible => "client library incompatible with daemon",
97 BadInterfaceIndex => "bad interface index",
98 Refused => "refused",
99 NoSuchRecord => "no such record",
100 NoAuth => "no auth",
101 NoSuchKey => "no such key",
102 NATTraversal => "NAT traversal",
103 DoubleNAT => "double NAT",
104 BadTime => "bad time",
105 BadSig => "bad signature",
106 BadKey => "bad key",
107 Transient => "transient",
108 ServiceNotRunning => "service not running",
109 NATPortMappingUnsupported => "NAT port mapping unsupported",
110 NATPortMappingDisabled => "NAT port mapping disabled",
111 NoRouter => "no router",
112 PollingMode => "polling mode",
113 Timeout => "timeout",
114 DefunctConnection => "defunct connection",
115 PolicyDenied => "policy denied",
116 NotPermitted => "not permitted",
117 StaleData => "stale data",
118 }
119 }
120}
121
122impl fmt::Display for ffi::DNSServiceError {
123 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
124 write!(f, "{}", self.description())
125 }
126}
127impl error::Error for ffi::DNSServiceError {
128 fn description(&self) -> &str {
129 self.description()
130 }
131}
132
133#[cfg(test)]
134mod tests {
135 use super::*;
136
137 #[test]
138 #[allow(deprecated)]
139 fn test_ffi_err_description() {
140 assert_eq!(
143 error::Error::description(&ffi::DNSServiceError::NoAuth),
144 "no auth"
145 );
146 }
147}