Skip to main content

tiny_ping/
error.rs

1pub type Result<T> = std::result::Result<T, Error>;
2
3/// An error resulting from a ping option-setting or send/receive operation.
4#[derive(Debug)]
5pub enum Error {
6    Io(std::io::Error),
7    IncorrectBufferSize,
8    NotIpv4Packet,
9    NotIcmpPacket,
10    NotIcmpv6Packet,
11    PayloadTooShort { got: usize, want: usize },
12    IOError(String),
13    NotEchoReply,
14    NotV6EchoReply,
15    Timeout,
16    OtherICMP,
17    InvalidSize,
18    InvalidPacket,
19    TooSmallHeader,
20    InvalidHeaderSize,
21    InvalidVersion,
22    UnknownProtocol,
23    Unimplemented,
24    UnsupportedSocketType,
25}
26
27impl From<std::io::Error> for Error {
28    fn from(error: std::io::Error) -> Self {
29        Self::Io(error)
30    }
31}
32
33impl std::fmt::Display for Error {
34    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
35        match self {
36            Error::Io(error) => write!(f, "io error: {error}"),
37            Error::IncorrectBufferSize => write!(f, "incorrect buffer size"),
38            Error::NotIpv4Packet => write!(f, "not an IPv4 packet"),
39            Error::NotIcmpPacket => write!(f, "not an ICMP packet"),
40            Error::NotIcmpv6Packet => write!(f, "not an ICMPv6 packet"),
41            Error::PayloadTooShort { got, want } => {
42                write!(f, "payload too short: got {got} bytes, want {want}")
43            }
44            Error::IOError(error) => write!(f, "io error: {error}"),
45            Error::NotEchoReply => write!(f, "not an ICMP echo reply"),
46            Error::NotV6EchoReply => write!(f, "not an ICMPv6 echo reply"),
47            Error::Timeout => write!(f, "ping timed out"),
48            Error::OtherICMP => write!(f, "received a non-echo ICMP packet"),
49            Error::InvalidSize => write!(f, "invalid packet size"),
50            Error::InvalidPacket => write!(f, "invalid packet"),
51            Error::TooSmallHeader => write!(f, "packet header is too small"),
52            Error::InvalidHeaderSize => write!(f, "invalid IP header size"),
53            Error::InvalidVersion => write!(f, "invalid IP version"),
54            Error::UnknownProtocol => write!(f, "unknown IP protocol"),
55            Error::Unimplemented => write!(f, "operation is not implemented"),
56            Error::UnsupportedSocketType => write!(f, "unsupported socket type"),
57        }
58    }
59}
60
61impl std::error::Error for Error {
62    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
63        match self {
64            Error::Io(error) => Some(error),
65            _ => None,
66        }
67    }
68}
69
70#[cfg(test)]
71mod tests {
72    use super::*;
73
74    #[test]
75    fn display_messages_are_not_empty() {
76        let errors = [
77            Error::Timeout,
78            Error::InvalidPacket,
79            Error::InvalidHeaderSize,
80            Error::UnsupportedSocketType,
81        ];
82
83        for error in errors {
84            assert!(!error.to_string().is_empty());
85        }
86    }
87}