use std::io;
use thiserror::Error;
#[derive(Error, Debug)]
pub enum SendError {
#[error("send failed: client closed or disconnecting")]
Closed,
#[error("send failed: timeout waiting for active state")]
Timeout,
#[error("send failed: broken pipe ({0})")]
BrokenPipe(String),
}
pub(crate) fn is_connection_drop_io_error(err: &io::Error) -> bool {
matches!(
err.kind(),
io::ErrorKind::BrokenPipe
| io::ErrorKind::ConnectionAborted
| io::ErrorKind::ConnectionReset
| io::ErrorKind::NotConnected
| io::ErrorKind::TimedOut
| io::ErrorKind::UnexpectedEof
)
}
#[cfg(test)]
mod tests {
use rstest::rstest;
use super::*;
#[rstest]
#[case(io::ErrorKind::BrokenPipe, true)]
#[case(io::ErrorKind::ConnectionAborted, true)]
#[case(io::ErrorKind::ConnectionReset, true)]
#[case(io::ErrorKind::NotConnected, true)]
#[case(io::ErrorKind::TimedOut, true)]
#[case(io::ErrorKind::UnexpectedEof, true)]
#[case(io::ErrorKind::InvalidInput, false)]
#[case(io::ErrorKind::PermissionDenied, false)]
fn connection_drop_io_error_classification(
#[case] kind: io::ErrorKind,
#[case] expected: bool,
) {
let err = io::Error::from(kind);
assert_eq!(is_connection_drop_io_error(&err), expected);
}
}