1 use crate::codec::SendError; 2 use crate::frame::{Reason, StreamId}; 3 4 use bytes::Bytes; 5 use std::fmt; 6 use std::io; 7 8 /// Either an H2 reason or an I/O error 9 #[derive(Clone, Debug)] 10 pub enum Error { 11 Reset(StreamId, Reason, Initiator), 12 GoAway(Bytes, Reason, Initiator), 13 Io(io::ErrorKind, Option<String>), 14 } 15 16 #[derive(Clone, Copy, Debug, PartialEq, Eq)] 17 pub enum Initiator { 18 User, 19 Library, 20 Remote, 21 } 22 23 impl Error { is_local(&self) -> bool24 pub(crate) fn is_local(&self) -> bool { 25 match *self { 26 Self::Reset(_, _, initiator) | Self::GoAway(_, _, initiator) => initiator.is_local(), 27 Self::Io(..) => true, 28 } 29 } 30 user_go_away(reason: Reason) -> Self31 pub(crate) fn user_go_away(reason: Reason) -> Self { 32 Self::GoAway(Bytes::new(), reason, Initiator::User) 33 } 34 library_reset(stream_id: StreamId, reason: Reason) -> Self35 pub(crate) fn library_reset(stream_id: StreamId, reason: Reason) -> Self { 36 Self::Reset(stream_id, reason, Initiator::Library) 37 } 38 library_go_away(reason: Reason) -> Self39 pub(crate) fn library_go_away(reason: Reason) -> Self { 40 Self::GoAway(Bytes::new(), reason, Initiator::Library) 41 } 42 library_go_away_data(reason: Reason, debug_data: impl Into<Bytes>) -> Self43 pub(crate) fn library_go_away_data(reason: Reason, debug_data: impl Into<Bytes>) -> Self { 44 Self::GoAway(debug_data.into(), reason, Initiator::Library) 45 } 46 remote_reset(stream_id: StreamId, reason: Reason) -> Self47 pub(crate) fn remote_reset(stream_id: StreamId, reason: Reason) -> Self { 48 Self::Reset(stream_id, reason, Initiator::Remote) 49 } 50 remote_go_away(debug_data: Bytes, reason: Reason) -> Self51 pub(crate) fn remote_go_away(debug_data: Bytes, reason: Reason) -> Self { 52 Self::GoAway(debug_data, reason, Initiator::Remote) 53 } 54 } 55 56 impl Initiator { is_local(&self) -> bool57 fn is_local(&self) -> bool { 58 match *self { 59 Self::User | Self::Library => true, 60 Self::Remote => false, 61 } 62 } 63 } 64 65 impl fmt::Display for Error { fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result66 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { 67 match *self { 68 Self::Reset(_, reason, _) | Self::GoAway(_, reason, _) => reason.fmt(fmt), 69 Self::Io(_, Some(ref inner)) => inner.fmt(fmt), 70 Self::Io(kind, None) => io::Error::from(kind).fmt(fmt), 71 } 72 } 73 } 74 75 impl From<io::ErrorKind> for Error { from(src: io::ErrorKind) -> Self76 fn from(src: io::ErrorKind) -> Self { 77 Error::Io(src, None) 78 } 79 } 80 81 impl From<io::Error> for Error { from(src: io::Error) -> Self82 fn from(src: io::Error) -> Self { 83 Error::Io(src.kind(), src.get_ref().map(|inner| inner.to_string())) 84 } 85 } 86 87 impl From<Error> for SendError { from(src: Error) -> Self88 fn from(src: Error) -> Self { 89 Self::Connection(src) 90 } 91 } 92