use std::fmt;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Reliability {
FireAndForget,
Reliable,
}
impl Reliability {
#[inline]
pub(crate) fn is_reliable(self) -> bool {
matches!(self, Reliability::Reliable)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CloseBehavior {
DrainThenClose,
DropAndClose,
}
pub const DEFAULT_STREAM_WINDOW_BYTES: u32 = 65_536;
#[derive(Debug, Clone, Copy)]
pub struct StreamConfig {
pub reliability: Reliability,
pub window_bytes: u32,
pub fairness_weight: u8,
pub close_behavior: CloseBehavior,
}
impl Default for StreamConfig {
fn default() -> Self {
Self {
reliability: Reliability::FireAndForget,
window_bytes: DEFAULT_STREAM_WINDOW_BYTES,
fairness_weight: 1,
close_behavior: CloseBehavior::DropAndClose,
}
}
}
impl StreamConfig {
pub fn new() -> Self {
Self::default()
}
pub fn with_reliability(mut self, reliability: Reliability) -> Self {
self.reliability = reliability;
self
}
pub fn with_window_bytes(mut self, bytes: u32) -> Self {
self.window_bytes = bytes;
self
}
pub fn with_fairness_weight(mut self, weight: u8) -> Self {
self.fairness_weight = weight.max(1);
self
}
pub fn with_close_behavior(mut self, behavior: CloseBehavior) -> Self {
self.close_behavior = behavior;
self
}
}
#[derive(Debug)]
pub enum StreamError {
Backpressure,
NotConnected,
Transport(String),
}
impl fmt::Display for StreamError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
StreamError::Backpressure => write!(f, "stream would block (queue full)"),
StreamError::NotConnected => write!(f, "stream not connected"),
StreamError::Transport(msg) => write!(f, "stream transport error: {}", msg),
}
}
}
impl std::error::Error for StreamError {}
#[derive(Debug, Clone, Copy)]
pub struct StreamStats {
pub tx_seq: u64,
pub rx_seq: u64,
pub inbound_pending: u64,
pub last_activity_ns: u64,
pub active: bool,
pub backpressure_events: u64,
pub tx_credit_remaining: u32,
pub tx_window: u32,
pub credit_grants_received: u64,
pub credit_grants_sent: u64,
}
#[derive(Debug, Clone)]
pub struct Stream {
pub(crate) peer_node_id: u64,
pub(crate) stream_id: u64,
pub(crate) epoch: u64,
pub(crate) config: StreamConfig,
}
impl Stream {
#[inline]
pub fn peer_node_id(&self) -> u64 {
self.peer_node_id
}
#[inline]
pub fn stream_id(&self) -> u64 {
self.stream_id
}
#[inline]
pub fn config(&self) -> &StreamConfig {
&self.config
}
}