      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
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145

    use crate::frame::{Reason, StreamId};

    use std::{error, fmt, io};

    /// Errors that are received
    #[derive(Debug)]
    pub enum RecvError {
        Connection(Reason),
        Stream { id: StreamId, reason: Reason },
        Io(io::Error),
    }

    /// Errors caused by sending a message
    #[derive(Debug)]
    pub enum SendError {
        /// User error
        User(UserError),

        /// Connection error prevents sending.
        Connection(Reason),

        /// I/O error
        Io(io::Error),
    }

    /// Errors caused by users of the library
    #[derive(Debug)]
    pub enum UserError {
        /// The stream ID is no longer accepting frames.
        InactiveStreamId,

        /// The stream is not currently expecting a frame of this type.
        UnexpectedFrameType,

        /// The payload size is too big
        PayloadTooBig,

        /// A header size is too big
        HeaderTooBig,

        /// The application attempted to initiate too many streams to remote.
        Rejected,

        /// The released capacity is larger than claimed capacity.
        ReleaseCapacityTooBig,

        /// The stream ID space is overflowed.
        ///
        /// A new connection is needed.
        OverflowedStreamId,

        /// Illegal headers, such as connection-specific headers.
        MalformedHeaders,

        /// Request submitted with relative URI.
        MissingUriSchemeAndAuthority,

        /// Calls `SendResponse::poll_reset` after having called `send_response`.
        PollResetAfterSendResponse,

        /// Calls `PingPong::send_ping` before receiving a pong.
        SendPingWhilePending,

        /// Tries to update local SETTINGS while ACK has not been received.
        SendSettingsWhilePending,

        /// Tries to send push promise to peer who has disabled server push
        PeerDisabledServerPush,
    }

    // ===== impl RecvError =====

    impl From<io::Error> for RecvError {
        fn from(src: io::Error) -> Self {
            RecvError::Io(src)
        }
    }

    impl error::Error for RecvError {}

    impl fmt::Display for RecvError {
        fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
            use self::RecvError::*;

            match *self {
                Connection(ref reason) => reason.fmt(fmt),
                Stream { ref reason, .. } => reason.fmt(fmt),
                Io(ref e) => e.fmt(fmt),
            }
        }
    }

    // ===== impl SendError =====

    impl error::Error for SendError {}

    impl fmt::Display for SendError {
        fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
            use self::SendError::*;

            match *self {
                User(ref e) => e.fmt(fmt),
                Connection(ref reason) => reason.fmt(fmt),
                Io(ref e) => e.fmt(fmt),
            }
        }
    }

    impl From<io::Error> for SendError {
        fn from(src: io::Error) -> Self {
            SendError::Io(src)
        }
    }

    impl From<UserError> for SendError {
        fn from(src: UserError) -> Self {
            SendError::User(src)
        }
    }

    // ===== impl UserError =====

    impl error::Error for UserError {}

    impl fmt::Display for UserError {
        fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
            use self::UserError::*;

            fmt.write_str(match *self {
                InactiveStreamId => "inactive stream",
                UnexpectedFrameType => "unexpected frame type",
                PayloadTooBig => "payload too big",
                HeaderTooBig => "header too big",
                Rejected => "rejected",
                ReleaseCapacityTooBig => "release capacity too big",
                OverflowedStreamId => "stream ID overflowed",
                MalformedHeaders => "malformed headers",
                MissingUriSchemeAndAuthority => "request URI missing scheme and authority",
                PollResetAfterSendResponse => "poll_reset after send_response is illegal",
                SendPingWhilePending => "send_ping before received previous pong",
                SendSettingsWhilePending => "sending SETTINGS before received previous ACK",
                PeerDisabledServerPush => "sending PUSH_PROMISE to peer who disabled server push",
            })
        }
    }