Skip to main content

android/adb/
error.rs

1//! Errors of the adb client.
2
3use std::fmt;
4use std::io;
5use std::net::SocketAddr;
6use std::path::PathBuf;
7
8/// Why an adb request failed.
9#[derive(Debug)]
10pub enum Error {
11    /// Nothing accepted a connection at the server's address.
12    ServerUnavailable { addr: SocketAddr, source: io::Error },
13    /// The adb server, or adbd behind it, answered `FAIL` to `request`.
14    Fail { request: String, message: String },
15    /// The connection serving `request` failed or passed its deadline.
16    Io { request: String, source: io::Error },
17    /// The peer answered `request` with bytes the protocol does not allow.
18    Protocol { request: String, detail: String },
19    /// `request` cannot be sent as given.
20    Invalid { request: String, detail: String },
21    /// A local file to push could not be read.
22    Local { path: PathBuf, source: io::Error },
23}
24
25impl Error {
26    /// The message of a `FAIL` answer, such as `closed` for a device service
27    /// that nothing listens on.
28    pub fn fail_message(&self) -> Option<&str> {
29        match self {
30            Error::Fail { message, .. } => Some(message),
31            _ => None,
32        }
33    }
34
35    /// Whether a connection passed its read or write deadline.
36    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}