1use std::fmt;
4use std::io;
5use std::net::SocketAddr;
6use std::path::PathBuf;
7
8#[derive(Debug)]
10pub enum Error {
11 ServerUnavailable { addr: SocketAddr, source: io::Error },
13 Fail { request: String, message: String },
15 Io { request: String, source: io::Error },
17 Protocol { request: String, detail: String },
19 Invalid { request: String, detail: String },
21 Local { path: PathBuf, source: io::Error },
23}
24
25impl Error {
26 pub fn fail_message(&self) -> Option<&str> {
29 match self {
30 Error::Fail { message, .. } => Some(message),
31 _ => None,
32 }
33 }
34
35 pub fn is_timeout(&self) -> bool {
37 matches!(
38 self,
39 Error::Io { source, .. }
40 if matches!(source.kind(), io::ErrorKind::TimedOut | io::ErrorKind::WouldBlock)
41 )
42 }
43}
44
45impl fmt::Display for Error {
46 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
47 match self {
48 Error::ServerUnavailable { addr, source } => write!(
49 f,
50 "no adb server at {addr} ({source}); start one with `adb start-server`"
51 ),
52 Error::Fail { request, message } => write!(f, "{request}: {message}"),
53 Error::Io { request, source } => write!(f, "{request}: {source}"),
54 Error::Protocol { request, detail } => write!(f, "{request}: {detail}"),
55 Error::Invalid { request, detail } => write!(f, "{request}: {detail}"),
56 Error::Local { path, source } => write!(f, "reading {}: {source}", path.display()),
57 }
58 }
59}
60
61impl std::error::Error for Error {
62 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
63 match self {
64 Error::ServerUnavailable { source, .. }
65 | Error::Io { source, .. }
66 | Error::Local { source, .. } => Some(source),
67 _ => None,
68 }
69 }
70}