1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
use std::error::Error;
use std::fmt;
use std::io::{self, ErrorKind};

#[derive(Debug)]
pub enum SocketError {
    ConnectionClosed,
    ConnectionReset,
    ConnectionTimedOut,
    InvalidAddress,
    InvalidReply,
    NotConnected,
    Other(String),
}

impl Error for SocketError {
    fn description(&self) -> &str {
        use self::SocketError::*;
        match *self {
            ConnectionClosed => "The socket is closed",
            ConnectionReset => "Connection reset by remote peer",
            ConnectionTimedOut => "Connection timed out",
            InvalidAddress => "Invalid address",
            InvalidReply => "The remote peer sent an invalid reply",
            NotConnected => "The socket is not connected",
            Other(ref s) => s,
        }
    }
}

impl fmt::Display for SocketError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{:?}", &self)
    }
}

impl From<SocketError> for io::Error {
    fn from(error: SocketError) -> io::Error {
        use self::SocketError::*;
        let kind = match error {
            ConnectionClosed | NotConnected => ErrorKind::NotConnected,
            ConnectionReset => ErrorKind::ConnectionReset,
            ConnectionTimedOut => ErrorKind::TimedOut,
            InvalidAddress => ErrorKind::InvalidInput,
            InvalidReply => ErrorKind::ConnectionRefused,
            Other(_) => ErrorKind::Other,
        };
        io::Error::new(kind, error.to_string())
    }
}

#[derive(Debug)]
pub enum ParseError {
    InvalidExtensionLength,
    InvalidPacketLength,
    InvalidPacketType(u8),
    UnsupportedVersion,
}

impl fmt::Display for ParseError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{:?}", &self)
    }
}

impl Error for ParseError {
    fn description(&self) -> &str {
        use self::ParseError::*;
        match *self {
            InvalidExtensionLength => "Invalid extension length (must be a non-zero multiple of 4)",
            InvalidPacketLength => "The packet is too small",
            InvalidPacketType(_) => "Invalid packet type",
            UnsupportedVersion => "Unsupported packet version",
        }
    }
}

impl From<ParseError> for io::Error {
    fn from(error: ParseError) -> io::Error {
        io::Error::new(ErrorKind::Other, error.to_string())
    }
}