use crate::error::ErrorKind;
use crate::error::{Error, Result};
use std::net::SocketAddr;
pub struct ErrorMapper;
impl ErrorMapper {
pub fn in_progress(err: Error) -> Result<()> {
match err {
Error::IoError(io_err) => match io_err.kind() {
ErrorKind::InProgress => Ok(()),
_ => Err(Error::IoError(io_err)),
},
err => Err(err),
}
}
#[must_use]
pub fn addr_in_use(err: Error, addr: SocketAddr) -> Error {
match err {
Error::IoError(io_err) => match io_err.kind() {
ErrorKind::Std(std::io::ErrorKind::AddrInUse) => Error::AddressInUse(addr),
_ => Error::IoError(io_err),
},
err => err,
}
}
#[allow(clippy::needless_pass_by_value)]
pub fn probe_failed(err: Error, kind: ErrorKind) -> Error {
match err {
Error::IoError(io_err) if io_err.kind() == kind => Error::ProbeFailed(io_err),
_ => err,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::error::IoError;
use std::io;
use std::net::{Ipv4Addr, SocketAddrV4};
const ADDR: SocketAddr = SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::UNSPECIFIED, 0));
#[test]
fn test_in_progress() {
let io_err = io::Error::from(ErrorKind::InProgress);
let err = Error::IoError(IoError::Bind(io_err, ADDR));
assert!(ErrorMapper::in_progress(err).is_ok());
}
#[test]
fn test_not_in_progress() {
let io_err = io::Error::from(ErrorKind::Std(io::ErrorKind::Other));
let err = Error::IoError(IoError::Bind(io_err, ADDR));
assert!(ErrorMapper::in_progress(err).is_err());
}
#[test]
fn test_addr_in_use() {
let io_err = io::Error::from(ErrorKind::Std(io::ErrorKind::AddrInUse));
let err = Error::IoError(IoError::Bind(io_err, ADDR));
let addr_in_use_err = ErrorMapper::addr_in_use(err, ADDR);
assert!(matches!(addr_in_use_err, Error::AddressInUse(ADDR)));
}
#[test]
fn test_not_addr_in_use() {
let io_err = io::Error::from(ErrorKind::Std(io::ErrorKind::Other));
let err = Error::IoError(IoError::Bind(io_err, ADDR));
let addr_in_use_err = ErrorMapper::addr_in_use(err, ADDR);
assert!(matches!(addr_in_use_err, Error::IoError(_)));
}
#[test]
fn test_probe_failed() {
let io_err = io::Error::from(ErrorKind::HostUnreachable);
let err = Error::IoError(IoError::Bind(io_err, ADDR));
let probe_err = ErrorMapper::probe_failed(err, ErrorKind::HostUnreachable);
assert!(matches!(probe_err, Error::ProbeFailed(_)));
}
}