| 1 | use std::{fmt, io}; |
| 2 | |
| 3 | /// An `ACK` error returned by the server. |
| 4 | #[derive(Clone, Debug, PartialEq, Eq)] |
| 5 | pub struct Ack { |
| 6 | pub code: u32, |
| 7 | /// Index of the failing command inside a command list. |
| 8 | pub index: u32, |
| 9 | pub command: String, |
| 10 | pub message: String, |
| 11 | } |
| 12 | |
| 13 | impl fmt::Display for Ack { |
| 14 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| 15 | if self.command.is_empty() { |
| 16 | write!(f, "{}", self.message) |
| 17 | } else { |
| 18 | write!(f, "{}: {}", self.command, self.message) |
| 19 | } |
| 20 | } |
| 21 | } |
| 22 | |
| 23 | #[derive(Debug, thiserror::Error)] |
| 24 | pub enum MpdError { |
| 25 | #[error("connection error: {0}")] |
| 26 | Io(#[from] io::Error), |
| 27 | #[error("MPD error: {0}")] |
| 28 | Ack(Ack), |
| 29 | #[error("protocol error: {0}")] |
| 30 | Protocol(String), |
| 31 | #[error("connection closed by server")] |
| 32 | Closed, |
| 33 | } |
| 34 | |
| 35 | impl MpdError { |
| 36 | /// Whether the connection is unusable after this error. |
| 37 | pub fn is_fatal(&self) -> bool { |
| 38 | !matches!(self, Self::Ack(_)) |
| 39 | } |
| 40 | } |
| 41 | |
| 42 | pub type MpdResult<T> = Result<T, MpdError>; |