1use std::{convert::Infallible, error::Error as StdError, fmt::Display};
2
3use crate::io::Id;
4
5#[derive(Debug)]
6pub enum Error {
7 Protocol(ProtocolError),
8 Io(std::io::Error),
9 Serialize(Option<bincode::Error>),
10 Driver,
11 Spawner,
12 Other(Box<dyn StdError + Send + Sync + 'static>),
13 Unspecified,
14}
15
16impl Display for Error {
17 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
18 match self {
19 Error::Protocol(e) => {
20 write!(f, "protocol error: {}", e)
21 }
22 Error::Io(e) => {
23 write!(f, "io error: {}", e)
24 }
25 Error::Serialize(e) => {
26 write!(f, "serialize error: ")?;
27 if let Some(e) = e {
28 write!(f, "{}", e)
29 } else {
30 write!(f, "internal error")
31 }
32 }
33 Error::Driver => {
34 write!(f, "driver stopped unexpectedly")
35 }
36 Error::Spawner => {
37 write!(f, "spawner stopped unexpectedly")
38 }
39 Error::Other(e) => {
40 write!(f, "other error: {}", e)
41 }
42 Error::Unspecified => {
43 write!(f, "unspecified error")
44 }
45 }
46 }
47}
48
49impl StdError for Error {
50 fn source(&self) -> Option<&(dyn StdError + 'static)> {
51 match self {
52 Error::Io(e) => Some(e),
53 Error::Serialize(e) => e.as_ref().map(|e| e.as_ref() as &(dyn StdError + 'static)),
54 Error::Other(e) => Some(e.as_ref() as &(dyn StdError + 'static)),
55 _ => None,
56 }
57 }
58}
59
60impl From<std::io::Error> for Error {
61 fn from(e: std::io::Error) -> Self {
62 Self::Io(e)
63 }
64}
65
66impl From<Infallible> for Error {
67 fn from(_: Infallible) -> Self {
68 unreachable!()
69 }
70}
71
72impl<E: std::error::Error + Sync + Send + 'static> From<Box<E>> for Error {
73 fn from(e: Box<E>) -> Self {
74 Self::Other(e)
75 }
76}
77
78#[derive(Debug)]
80pub enum ProtocolError {
81 MartianResponse,
82 ResponseMismatch(Id),
83}
84
85impl Display for ProtocolError {
86 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
87 match self {
88 ProtocolError::MartianResponse => {
89 write!(f, "response of non-exist request")
90 }
91 ProtocolError::ResponseMismatch(_) => {
92 write!(f, "response for different function")
93 }
94 }
95 }
96}
97
98impl StdError for ProtocolError {}
99
100impl From<ProtocolError> for Error {
101 fn from(e: ProtocolError) -> Self {
102 Self::Protocol(e)
103 }
104}
105
106pub type Result<T> = std::result::Result<T, Error>;