summaryrefslogtreecommitdiffstats
path: root/third_party/rust/h2/src/proto/error.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/h2/src/proto/error.rs')
-rw-r--r--third_party/rust/h2/src/proto/error.rs87
1 files changed, 87 insertions, 0 deletions
diff --git a/third_party/rust/h2/src/proto/error.rs b/third_party/rust/h2/src/proto/error.rs
new file mode 100644
index 0000000000..1972372637
--- /dev/null
+++ b/third_party/rust/h2/src/proto/error.rs
@@ -0,0 +1,87 @@
+use crate::codec::SendError;
+use crate::frame::{Reason, StreamId};
+
+use bytes::Bytes;
+use std::fmt;
+use std::io;
+
+/// Either an H2 reason or an I/O error
+#[derive(Clone, Debug)]
+pub enum Error {
+ Reset(StreamId, Reason, Initiator),
+ GoAway(Bytes, Reason, Initiator),
+ Io(io::ErrorKind, Option<String>),
+}
+
+#[derive(Clone, Copy, Debug, PartialEq)]
+pub enum Initiator {
+ User,
+ Library,
+ Remote,
+}
+
+impl Error {
+ pub(crate) fn is_local(&self) -> bool {
+ match *self {
+ Self::Reset(_, _, initiator) | Self::GoAway(_, _, initiator) => initiator.is_local(),
+ Self::Io(..) => true,
+ }
+ }
+
+ pub(crate) fn user_go_away(reason: Reason) -> Self {
+ Self::GoAway(Bytes::new(), reason, Initiator::User)
+ }
+
+ pub(crate) fn library_reset(stream_id: StreamId, reason: Reason) -> Self {
+ Self::Reset(stream_id, reason, Initiator::Library)
+ }
+
+ pub(crate) fn library_go_away(reason: Reason) -> Self {
+ Self::GoAway(Bytes::new(), reason, Initiator::Library)
+ }
+
+ pub(crate) fn remote_reset(stream_id: StreamId, reason: Reason) -> Self {
+ Self::Reset(stream_id, reason, Initiator::Remote)
+ }
+
+ pub(crate) fn remote_go_away(debug_data: Bytes, reason: Reason) -> Self {
+ Self::GoAway(debug_data, reason, Initiator::Remote)
+ }
+}
+
+impl Initiator {
+ fn is_local(&self) -> bool {
+ match *self {
+ Self::User | Self::Library => true,
+ Self::Remote => false,
+ }
+ }
+}
+
+impl fmt::Display for Error {
+ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+ match *self {
+ Self::Reset(_, reason, _) | Self::GoAway(_, reason, _) => reason.fmt(fmt),
+ Self::Io(_, Some(ref inner)) => inner.fmt(fmt),
+ Self::Io(kind, None) => io::Error::from(kind).fmt(fmt),
+ }
+ }
+}
+
+impl From<io::ErrorKind> for Error {
+ fn from(src: io::ErrorKind) -> Self {
+ Error::Io(src.into(), None)
+ }
+}
+
+impl From<io::Error> for Error {
+ fn from(src: io::Error) -> Self {
+ Error::Io(src.kind(), src.get_ref().map(|inner| inner.to_string()))
+ }
+}
+
+impl From<Error> for SendError {
+ fn from(src: Error) -> Self {
+ Self::Connection(src)
+ }
+}