use std::io;
use thiserror::Error;
#[derive(Debug, Error)]
pub enum StreamError {
#[error("Connection closed")]
Closed,
#[error("stream future polled after completion")]
PolledAfterCompletion,
#[error("Connection reset")]
Reset,
#[error("Timeout waiting for symbol")]
Timeout,
#[error("Authentication failed: {reason}")]
AuthenticationFailed {
reason: String,
},
#[error("Protocol error: {details}")]
ProtocolError {
details: String,
},
#[error("I/O error: {source}")]
Io {
#[from]
source: io::Error,
},
#[error("Cancelled")]
Cancelled,
}
#[derive(Debug, Error)]
pub enum SinkError {
#[error("Connection closed")]
Closed,
#[error("sink future polled after completion")]
PolledAfterCompletion,
#[error("Buffer full")]
BufferFull,
#[error("Send failed: {reason}")]
SendFailed {
reason: String,
},
#[error("I/O error: {source}")]
Io {
#[from]
source: io::Error,
},
#[error("Cancelled")]
Cancelled,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn stream_error_debug_display() {
let closed = StreamError::Closed;
assert!(format!("{closed:?}").contains("Closed"));
assert_eq!(format!("{closed}"), "Connection closed");
let done = StreamError::PolledAfterCompletion;
assert_eq!(format!("{done}"), "stream future polled after completion");
let reset = StreamError::Reset;
assert_eq!(format!("{reset}"), "Connection reset");
let timeout = StreamError::Timeout;
assert_eq!(format!("{timeout}"), "Timeout waiting for symbol");
let cancelled = StreamError::Cancelled;
assert_eq!(format!("{cancelled}"), "Cancelled");
let auth = StreamError::AuthenticationFailed {
reason: "bad token".into(),
};
assert!(format!("{auth}").contains("bad token"));
let proto = StreamError::ProtocolError {
details: "invalid frame".into(),
};
assert!(format!("{proto}").contains("invalid frame"));
}
#[test]
fn stream_error_from_io() {
let io_err = io::Error::new(io::ErrorKind::BrokenPipe, "pipe broken");
let stream_err: StreamError = io_err.into();
assert!(format!("{stream_err}").contains("pipe broken"));
assert!(matches!(stream_err, StreamError::Io { .. }));
}
#[test]
fn sink_error_debug_display() {
let closed = SinkError::Closed;
assert!(format!("{closed:?}").contains("Closed"));
assert_eq!(format!("{closed}"), "Connection closed");
let done = SinkError::PolledAfterCompletion;
assert_eq!(format!("{done}"), "sink future polled after completion");
let full = SinkError::BufferFull;
assert_eq!(format!("{full}"), "Buffer full");
let cancelled = SinkError::Cancelled;
assert_eq!(format!("{cancelled}"), "Cancelled");
let send_failed = SinkError::SendFailed {
reason: "queue overflow".into(),
};
assert!(format!("{send_failed}").contains("queue overflow"));
}
#[test]
fn sink_error_from_io() {
let io_err = io::Error::new(io::ErrorKind::ConnectionRefused, "refused");
let sink_err: SinkError = io_err.into();
assert!(format!("{sink_err}").contains("refused"));
assert!(matches!(sink_err, SinkError::Io { .. }));
}
}