use std::fmt;
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct EpisodeId(u64);
impl EpisodeId {
pub const fn new(value: u64) -> Self {
Self(value)
}
pub const fn get(self) -> u64 {
self.0
}
}
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct AttemptGeneration(u64);
impl AttemptGeneration {
pub const fn new(value: u64) -> Self {
Self(value)
}
pub const fn get(self) -> u64 {
self.0
}
}
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct ConnectionId([u8; 16]);
impl ConnectionId {
pub const fn new(value: [u8; 16]) -> Self {
Self(value)
}
pub const fn as_bytes(&self) -> &[u8; 16] {
&self.0
}
}
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct Incarnation(u64);
impl Incarnation {
pub const fn new(value: u64) -> Self {
Self(value)
}
pub const fn get(self) -> u64 {
self.0
}
}
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct ConnectionKey {
pub connection_id: ConnectionId,
pub incarnation: Incarnation,
}
#[derive(Clone, Default, Eq, PartialEq)]
pub struct OpaqueBytes(Vec<u8>);
impl OpaqueBytes {
pub const fn new(bytes: Vec<u8>) -> Self {
Self(bytes)
}
pub fn as_slice(&self) -> &[u8] {
&self.0
}
pub const fn len(&self) -> usize {
self.0.len()
}
pub const fn is_empty(&self) -> bool {
self.0.is_empty()
}
pub fn into_vec(self) -> Vec<u8> {
self.0
}
}
impl fmt::Debug for OpaqueBytes {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter
.debug_struct("OpaqueBytes")
.field("len", &self.len())
.finish_non_exhaustive()
}
}
impl From<Vec<u8>> for OpaqueBytes {
fn from(bytes: Vec<u8>) -> Self {
Self::new(bytes)
}
}
impl From<&[u8]> for OpaqueBytes {
fn from(bytes: &[u8]) -> Self {
Self::new(bytes.to_vec())
}
}
#[derive(Clone, Default, Eq, PartialEq)]
pub struct AuthenticatedPeerBinding(Vec<u8>);
impl AuthenticatedPeerBinding {
pub const fn new(bytes: Vec<u8>) -> Self {
Self(bytes)
}
pub fn as_slice(&self) -> &[u8] {
&self.0
}
pub fn into_vec(self) -> Vec<u8> {
self.0
}
}
impl fmt::Debug for AuthenticatedPeerBinding {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter
.debug_struct("AuthenticatedPeerBinding")
.field("len", &self.0.len())
.finish_non_exhaustive()
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum CarrierEstablishedCause {
ExplicitAction,
ProvedOnline,
EstablishedConnectionFate,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum CarrierConnectFailureStage {
Dial,
Handshake,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum CarrierConnectFailureDisposition {
Park,
Stop,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct CarrierConnectFailureCause {
stage: CarrierConnectFailureStage,
disposition: CarrierConnectFailureDisposition,
}
impl CarrierConnectFailureCause {
pub const fn new(
stage: CarrierConnectFailureStage,
disposition: CarrierConnectFailureDisposition,
) -> Self {
Self { stage, disposition }
}
pub const fn stage(self) -> CarrierConnectFailureStage {
self.stage
}
pub const fn disposition(self) -> CarrierConnectFailureDisposition {
self.disposition
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum CarrierParkedCause {
AwaitingAction,
Offline,
EstablishedConnectionFate(CarrierLostCause),
ConnectFailed(CarrierConnectFailureCause),
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum CarrierRefusal {
FrameTooLarge { announced: u32, maximum: usize },
TruncatedLengthPrefix { received: usize },
TruncatedFrame { announced: u32, received: usize },
TrailingFrameBytes { announced: u32, received: usize },
NonBinaryWebSocketMessage,
QueueCapacityExceeded {
queued_frames: usize,
queued_bytes: usize,
},
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum CarrierCloseCause {
ApplicationRequested,
Replaced,
Shutdown,
Refused(CarrierRefusal),
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum CarrierLostCause {
CleanClose,
TransportError,
Replaced,
LocalClose(CarrierCloseCause),
Shutdown,
MalformedFrame(CarrierRefusal),
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum CarrierStoppedCause {
ExplicitClose(CarrierCloseCause),
Shutdown,
ConnectFailed(CarrierConnectFailureCause),
IdentitySpaceExhausted,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum CarrierSendRefusal {
Backpressured,
FrameTooLarge { announced: usize, maximum: usize },
QueueCapacityExceeded {
queued_frames: usize,
queued_bytes: usize,
},
ConnectionNotCurrent { key: ConnectionKey },
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum CarrierSendOutcome {
Accepted,
Refused(CarrierSendRefusal),
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum CarrierEvent {
Established {
episode: EpisodeId,
generation: AttemptGeneration,
key: ConnectionKey,
authenticated_peer_binding: AuthenticatedPeerBinding,
cause: CarrierEstablishedCause,
},
ConnectFailed {
episode: EpisodeId,
generation: AttemptGeneration,
cause: CarrierConnectFailureCause,
},
Parked {
episode: EpisodeId,
cause: CarrierParkedCause,
},
Stopped {
episode: EpisodeId,
cause: CarrierStoppedCause,
},
FrameReceived {
key: ConnectionKey,
bytes: OpaqueBytes,
},
SendReady {
key: ConnectionKey,
},
Refused {
key: ConnectionKey,
refusal: CarrierRefusal,
},
Lost {
key: ConnectionKey,
cause: CarrierLostCause,
},
}
pub trait Carrier {
fn send(&mut self, key: ConnectionKey, bytes: OpaqueBytes) -> CarrierSendOutcome;
fn close(&mut self, key: ConnectionKey, cause: CarrierCloseCause);
}