1use futures_core::stream::TryStream;
2use futures_sink::Sink;
3use std::{error, fmt};
4
5pub enum Error<T, I>
7where
8 T: Sink<I> + TryStream,
9{
10 BrokenTransportSend(<T as Sink<I>>::Error),
12
13 BrokenTransportRecv(Option<<T as TryStream>::Error>),
17
18 TransportFull,
22
23 ClientDropped,
25
26 Desynchronized,
28}
29
30impl<T, I> fmt::Display for Error<T, I>
31where
32 T: Sink<I> + TryStream,
33 <T as Sink<I>>::Error: fmt::Display,
34 <T as TryStream>::Error: fmt::Display,
35{
36 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
37 match *self {
38 Error::BrokenTransportSend(_) => f.pad("underlying transport failed to send a request"),
39 Error::BrokenTransportRecv(Some(_)) => {
40 f.pad("underlying transport failed while attempting to receive a response")
41 }
42 Error::BrokenTransportRecv(None) => f.pad("transport closed with in-flight requests"),
43 Error::TransportFull => f.pad("no more in-flight requests allowed"),
44 Error::ClientDropped => f.pad("Client was dropped"),
45 Error::Desynchronized => f.pad("server sent a response the client did not expect"),
46 }
47 }
48}
49
50impl<T, I> fmt::Debug for Error<T, I>
51where
52 T: Sink<I> + TryStream,
53 <T as Sink<I>>::Error: fmt::Debug,
54 <T as TryStream>::Error: fmt::Debug,
55{
56 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
57 match *self {
58 Error::BrokenTransportSend(ref se) => write!(f, "BrokenTransportSend({:?})", se),
59 Error::BrokenTransportRecv(Some(ref se)) => write!(f, "BrokenTransportRecv({:?})", se),
60 Error::BrokenTransportRecv(None) => f.pad("BrokenTransportRecv"),
61 Error::TransportFull => f.pad("TransportFull"),
62 Error::ClientDropped => f.pad("ClientDropped"),
63 Error::Desynchronized => f.pad("Desynchronized"),
64 }
65 }
66}
67
68impl<T, I> error::Error for Error<T, I>
69where
70 T: Sink<I> + TryStream,
71 <T as Sink<I>>::Error: error::Error + 'static,
72 <T as TryStream>::Error: error::Error + 'static,
73{
74 fn source(&self) -> Option<&(dyn error::Error + 'static)> {
75 match *self {
76 Error::BrokenTransportSend(ref se) => Some(se),
77 Error::BrokenTransportRecv(Some(ref se)) => Some(se),
78 _ => None,
79 }
80 }
81}
82
83impl<T, I> Error<T, I>
84where
85 T: Sink<I> + TryStream,
86{
87 pub(crate) fn from_sink_error(e: <T as Sink<I>>::Error) -> Self {
88 Error::BrokenTransportSend(e)
89 }
90
91 pub(crate) fn from_stream_error(e: <T as TryStream>::Error) -> Self {
92 Error::BrokenTransportRecv(Some(e))
93 }
94}