Skip to main content

surge_ping/
error.rs

1#![allow(dead_code)]
2use std::{io, net::IpAddr};
3
4use thiserror::Error;
5
6use crate::{icmp::PingSequence, PingIdentifier};
7
8pub type Result<T> = std::result::Result<T, SurgeError>;
9
10/// An error resulting from a ping option-setting or send/receive operation.
11///
12#[derive(Error, Debug)]
13pub enum SurgeError {
14    #[error("buffer size was too small")]
15    IncorrectBufferSize,
16    #[error("malformed packet: {0}")]
17    MalformedPacket(#[from] MalformedPacketError),
18    #[error("io error: {0}")]
19    IOError(#[from] io::Error),
20    #[error("Request timeout for icmp_seq {seq}")]
21    Timeout { seq: PingSequence },
22    #[error("Echo Request packet.")]
23    EchoRequestPacket,
24    #[error("Network error.")]
25    NetworkError,
26    #[error("Multiple identical request")]
27    IdenticalRequests {
28        host: IpAddr,
29        ident: Option<PingIdentifier>,
30        seq: PingSequence,
31    },
32    #[error("Client has been destroyed, ping operations are no longer available")]
33    ClientDestroyed,
34}
35
36#[derive(Error, Debug)]
37pub enum MalformedPacketError {
38    #[error("expected an Ipv4Packet")]
39    NotIpv4Packet,
40    #[error("expected an Ipv6Packet")]
41    NotIpv6Packet,
42    #[error("expected an Icmpv4Packet payload")]
43    NotIcmpv4Packet,
44    #[error("expected an Icmpv6Packet")]
45    NotIcmpv6Packet,
46    #[error("payload too short, got {got}, want {want}")]
47    PayloadTooShort { got: usize, want: usize },
48}
49
50#[cfg(test)]
51mod tests {
52    use super::*;
53
54    #[test]
55    fn test_surge_error_display() {
56        let err = SurgeError::IncorrectBufferSize;
57        assert_eq!(err.to_string(), "buffer size was too small");
58
59        let err = SurgeError::NetworkError;
60        assert_eq!(err.to_string(), "Network error.");
61
62        let err = SurgeError::EchoRequestPacket;
63        assert_eq!(err.to_string(), "Echo Request packet.");
64
65        let err = SurgeError::ClientDestroyed;
66        assert_eq!(
67            err.to_string(),
68            "Client has been destroyed, ping operations are no longer available"
69        );
70    }
71
72    #[test]
73    fn test_surge_error_timeout() {
74        let err = SurgeError::Timeout { seq: PingSequence(5) };
75        assert_eq!(err.to_string(), "Request timeout for icmp_seq 5");
76    }
77
78    #[test]
79    fn test_surge_error_identical_requests() {
80        let host: IpAddr = "192.168.1.1".parse().unwrap();
81        let err = SurgeError::IdenticalRequests {
82            host,
83            ident: Some(PingIdentifier(42)),
84            seq: PingSequence(10),
85        };
86        assert_eq!(
87            err.to_string(),
88            "Multiple identical request"
89        );
90    }
91
92    #[test]
93    fn test_malformed_packet_error_display() {
94        let err = MalformedPacketError::NotIpv4Packet;
95        assert_eq!(err.to_string(), "expected an Ipv4Packet");
96
97        let err = MalformedPacketError::NotIpv6Packet;
98        assert_eq!(err.to_string(), "expected an Ipv6Packet");
99
100        let err = MalformedPacketError::NotIcmpv4Packet;
101        assert_eq!(err.to_string(), "expected an Icmpv4Packet payload");
102
103        let err = MalformedPacketError::NotIcmpv6Packet;
104        assert_eq!(err.to_string(), "expected an Icmpv6Packet");
105    }
106
107    #[test]
108    fn test_malformed_packet_error_payload_too_short() {
109        let err = MalformedPacketError::PayloadTooShort { got: 10, want: 20 };
110        assert_eq!(err.to_string(), "payload too short, got 10, want 20");
111    }
112
113    #[test]
114    fn test_surge_error_from_io() {
115        let io_err = io::Error::new(io::ErrorKind::PermissionDenied, "test");
116        let surge_err: SurgeError = io_err.into();
117        assert!(matches!(surge_err, SurgeError::IOError(_)));
118    }
119
120    #[test]
121    fn test_surge_error_from_malformed_packet() {
122        let malformed_err = MalformedPacketError::NotIpv4Packet;
123        let surge_err: SurgeError = malformed_err.into();
124        assert!(matches!(surge_err, SurgeError::MalformedPacket(_)));
125    }
126}