#![doc = "Protocol engine boundaries for MSRT."]
pub(crate) mod codec;
pub(crate) mod config;
pub(crate) mod state;
pub use config::EngineConfig;
use crate::core::{Error, MessageId, PacketIndex, PacketType, Result};
use state::EngineState;
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Engine {
pub(crate) config: EngineConfig,
pub(crate) state: EngineState,
}
impl Engine {
#[must_use]
pub const fn new(config: EngineConfig) -> Self {
Self {
config,
state: EngineState::new(config.initial_message_id),
}
}
pub fn poll<'a>(&mut self, now_ms: u64, tx_buf: &'a mut [u8]) -> Result<EnginePoll<'a>> {
self.state.poll(&self.config, now_ms, tx_buf)
}
pub fn send(&mut self, message: &[u8]) -> Result<MessageId> {
self.state.send_data(&self.config, message)
}
pub fn send_log(&mut self, message: &[u8]) -> Result<MessageId> {
self.state.send_log(&self.config, message)
}
pub fn receive(&mut self, bytes: &[u8]) -> ReceiveReport {
self.state.receive(&self.config, bytes)
}
}
impl Default for Engine {
fn default() -> Self {
Self::new(EngineConfig::default())
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[allow(clippy::large_enum_variant)]
pub enum EnginePoll<'a> {
Transmit {
bytes: &'a [u8],
attempts: u8,
},
Message(MessageEvent),
SendFailed(SendFailedEvent),
Idle,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct MessageEvent {
pub packet_type: PacketType,
pub message_id: MessageId,
pub bytes: [u8; 256],
pub len: usize,
}
impl MessageEvent {
#[must_use]
pub const fn as_bytes(&self) -> &[u8] {
self.bytes.split_at(self.len).0
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct SendFailedEvent {
pub packet_type: PacketType,
pub message_id: MessageId,
pub reason: SendFailureReason,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum SendFailureReason {
RetryLimitReached,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum ReceiveReport {
Packet {
packet_index: PacketIndex,
},
Duplicate {
packet_index: PacketIndex,
},
Ack {
packet_index: PacketIndex,
},
Ping,
Pong,
Noise {
skipped: usize,
},
Corrupted,
Incomplete {
needed: Option<usize>,
},
Error(Error),
}