1use std::error::Error as StdError;
4use std::fmt;
5
6#[derive(Debug)]
15pub enum Error {
16 WouldBlock,
18
19 Stopped,
21
22 Disconnected(String),
24
25 InvalidConfig(String),
27
28 Backend(Box<dyn StdError + Send + Sync>),
30}
31
32impl fmt::Display for Error {
33 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
34 match self {
35 Error::WouldBlock => write!(f, "would block: device cannot accept more data"),
36 Error::Stopped => write!(f, "stopped: stream was explicitly stopped"),
37 Error::Disconnected(msg) => write!(f, "disconnected: {}", msg),
38 Error::InvalidConfig(msg) => write!(f, "invalid configuration: {}", msg),
39 Error::Backend(e) => write!(f, "backend error: {}", e),
40 }
41 }
42}
43
44impl StdError for Error {
45 fn source(&self) -> Option<&(dyn StdError + 'static)> {
46 match self {
47 Error::Backend(e) => Some(e.as_ref()),
48 _ => None,
49 }
50 }
51}
52
53impl Error {
54 pub fn disconnected(msg: impl Into<String>) -> Self {
56 Error::Disconnected(msg.into())
57 }
58
59 pub fn invalid_config(msg: impl Into<String>) -> Self {
61 Error::InvalidConfig(msg.into())
62 }
63
64 pub fn backend(err: impl StdError + Send + Sync + 'static) -> Self {
66 Error::Backend(Box::new(err))
67 }
68
69 pub fn is_would_block(&self) -> bool {
71 matches!(self, Error::WouldBlock)
72 }
73
74 pub fn is_disconnected(&self) -> bool {
76 matches!(self, Error::Disconnected(_))
77 }
78
79 pub fn is_stopped(&self) -> bool {
81 matches!(self, Error::Stopped)
82 }
83}
84
85impl From<std::io::Error> for Error {
86 fn from(err: std::io::Error) -> Self {
87 if err.kind() == std::io::ErrorKind::WouldBlock {
88 Error::WouldBlock
89 } else {
90 Error::Backend(Box::new(err))
91 }
92 }
93}
94
95pub type Result<T> = std::result::Result<T, Error>;