async_dnssd/
error.rs

1use std::{
2	error,
3	fmt,
4	io,
5};
6
7use crate::ffi;
8
9/// API Error
10pub enum Error {
11	/// If error code used some recognized name
12	KnownError(ffi::DNSServiceError),
13	/// Unrecognized error codes
14	UnknownError(i32),
15	/// IO error
16	IoError(io::Error),
17}
18
19impl Error {
20	/// Check if a raw error code represents an error, and convert it
21	/// accordingly.  (Not all codes are treated as an error, including
22	/// `0`).
23	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::new(io::ErrorKind::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			NoCache => "no cache",
92			AlreadyRegistered => "already registered",
93			NameConflict => "name conflict",
94			Invalid => "invalid",
95			Incompatible => "client library incompatible with daemon",
96			BadInterfaceIndex => "bad interface index",
97			Refused => "refused",
98			NoSuchRecord => "no such record",
99			NoAuth => "no auth",
100			NoSuchKey => "no such key",
101			NoValue => "no value",
102			BufferTooSmall => "buffer too small",
103		}
104	}
105}
106
107impl fmt::Display for ffi::DNSServiceError {
108	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
109		write!(f, "{}", self.description())
110	}
111}
112impl error::Error for ffi::DNSServiceError {
113	fn description(&self) -> &str {
114		self.description()
115	}
116}
117
118#[cfg(test)]
119mod tests {
120	use super::*;
121
122	#[test]
123	#[allow(deprecated)]
124	fn test_ffi_err_description() {
125		// make sure Error::description still works, although we now provide a
126		// (non-trait) description method
127		assert_eq!(
128			error::Error::description(&ffi::DNSServiceError::NoAuth),
129			"no auth"
130		);
131	}
132}