use std::fmt;
use bytes::Bytes;
use crate::{BearerToken, BindingId, Destination, PipeId, SessionId};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u8)]
pub enum ErrorCode {
InvalidArgument = 1,
Unauthenticated = 2,
PermissionDenied = 3,
NotFound = 4,
FailedPrecondition = 5,
Unavailable = 6,
DeadlineExceeded = 7,
ResourceExhausted = 8,
Cancelled = 9,
ProtocolError = 10,
Internal = 11,
AlreadyExists = 12,
}
impl ErrorCode {
#[must_use]
pub const fn metric_name(self) -> &'static str {
match self {
Self::InvalidArgument => "invalid_argument",
Self::Unauthenticated => "unauthenticated",
Self::PermissionDenied => "permission_denied",
Self::NotFound => "not_found",
Self::FailedPrecondition => "failed_precondition",
Self::Unavailable => "unavailable",
Self::DeadlineExceeded => "deadline_exceeded",
Self::ResourceExhausted => "resource_exhausted",
Self::Cancelled => "cancelled",
Self::ProtocolError => "protocol_error",
Self::Internal => "internal",
Self::AlreadyExists => "already_exists",
}
}
#[must_use]
pub fn from_wire(value: u8) -> Option<Self> {
match value {
1 => Some(Self::InvalidArgument),
2 => Some(Self::Unauthenticated),
3 => Some(Self::PermissionDenied),
4 => Some(Self::NotFound),
5 => Some(Self::FailedPrecondition),
6 => Some(Self::Unavailable),
7 => Some(Self::DeadlineExceeded),
8 => Some(Self::ResourceExhausted),
9 => Some(Self::Cancelled),
10 => Some(Self::ProtocolError),
11 => Some(Self::Internal),
12 => Some(Self::AlreadyExists),
_ => None,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u8)]
pub enum PeerObservation {
NotObserved = 1,
MaybeObserved = 2,
Observed = 3,
}
impl PeerObservation {
#[must_use]
pub fn from_wire(value: u8) -> Option<Self> {
match value {
1 => Some(Self::NotObserved),
2 => Some(Self::MaybeObserved),
3 => Some(Self::Observed),
_ => None,
}
}
}
#[derive(Clone, PartialEq, Eq)]
pub enum Frame {
Hello,
Welcome {
session_id: SessionId,
},
SessionRejected {
code: ErrorCode,
message: String,
},
Publish {
request_id: u64,
destination: Destination,
access_token: BearerToken,
},
Published {
request_id: u64,
binding_id: BindingId,
},
PublishFailed {
request_id: u64,
code: ErrorCode,
message: String,
},
Unpublish {
request_id: u64,
binding_id: BindingId,
},
Unpublished {
request_id: u64,
},
Dial {
connection_id: u64,
destination: Destination,
access_token: BearerToken,
},
Offer {
pipe_id: PipeId,
binding_id: BindingId,
destination: Destination,
},
OfferAccepted {
pipe_id: PipeId,
},
OfferRejected {
pipe_id: PipeId,
code: ErrorCode,
message: String,
},
Opened {
pipe_id: PipeId,
},
DialFailed {
connection_id: u64,
code: ErrorCode,
observation: PeerObservation,
message: String,
},
Data {
pipe_id: PipeId,
payload: Bytes,
},
Fin {
pipe_id: PipeId,
},
Close {
pipe_id: PipeId,
},
Reset {
pipe_id: PipeId,
code: ErrorCode,
message: String,
},
Ping {
nonce: u64,
},
Pong {
nonce: u64,
},
Cancel {
pipe_id: PipeId,
},
}
impl fmt::Debug for Frame {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Hello => formatter.write_str("Hello"),
Self::Welcome { session_id } => formatter
.debug_struct("Welcome")
.field("session_id", session_id)
.finish(),
Self::SessionRejected { code, message } => formatter
.debug_struct("SessionRejected")
.field("code", code)
.field("message", message)
.finish(),
Self::Publish {
request_id,
destination,
access_token,
} => formatter
.debug_struct("Publish")
.field("request_id", request_id)
.field("destination", destination)
.field("access_token", access_token)
.finish(),
Self::Published {
request_id,
binding_id,
} => formatter
.debug_struct("Published")
.field("request_id", request_id)
.field("binding_id", binding_id)
.finish(),
Self::PublishFailed {
request_id,
code,
message,
} => formatter
.debug_struct("PublishFailed")
.field("request_id", request_id)
.field("code", code)
.field("message", message)
.finish(),
Self::Unpublish {
request_id,
binding_id,
} => formatter
.debug_struct("Unpublish")
.field("request_id", request_id)
.field("binding_id", binding_id)
.finish(),
Self::Unpublished { request_id } => formatter
.debug_struct("Unpublished")
.field("request_id", request_id)
.finish(),
Self::Dial {
connection_id,
destination,
access_token,
} => formatter
.debug_struct("Dial")
.field("connection_id", connection_id)
.field("destination", destination)
.field("access_token", access_token)
.finish(),
Self::Offer {
pipe_id,
binding_id,
destination,
} => formatter
.debug_struct("Offer")
.field("pipe_id", pipe_id)
.field("binding_id", binding_id)
.field("destination", destination)
.finish(),
Self::OfferAccepted { pipe_id } => formatter
.debug_struct("OfferAccepted")
.field("pipe_id", pipe_id)
.finish(),
Self::OfferRejected {
pipe_id,
code,
message,
} => formatter
.debug_struct("OfferRejected")
.field("pipe_id", pipe_id)
.field("code", code)
.field("message", message)
.finish(),
Self::Opened { pipe_id } => formatter
.debug_struct("Opened")
.field("pipe_id", pipe_id)
.finish(),
Self::DialFailed {
connection_id,
code,
observation,
message,
} => formatter
.debug_struct("DialFailed")
.field("connection_id", connection_id)
.field("code", code)
.field("observation", observation)
.field("message", message)
.finish(),
Self::Data { pipe_id, payload } => formatter
.debug_struct("Data")
.field("pipe_id", pipe_id)
.field("payload_len", &payload.len())
.finish(),
Self::Fin { pipe_id } => formatter
.debug_struct("Fin")
.field("pipe_id", pipe_id)
.finish(),
Self::Close { pipe_id } => formatter
.debug_struct("Close")
.field("pipe_id", pipe_id)
.finish(),
Self::Reset {
pipe_id,
code,
message,
} => formatter
.debug_struct("Reset")
.field("pipe_id", pipe_id)
.field("code", code)
.field("message", message)
.finish(),
Self::Ping { nonce } => formatter
.debug_struct("Ping")
.field("nonce", nonce)
.finish(),
Self::Pong { nonce } => formatter
.debug_struct("Pong")
.field("nonce", nonce)
.finish(),
Self::Cancel { pipe_id } => formatter
.debug_struct("Cancel")
.field("pipe_id", pipe_id)
.finish(),
}
}
}