leodos_protocols/transport/srspp/api/tokio/mod.rs
1//! Tokio-based async driver for srspp.
2//!
3//! Provides separate sender and receiver types for point-to-point communication.
4//!
5//! ## Sender Example
6//!
7//! ```ignore
8//! let sender = SrsppSender::new(config, link);
9//!
10//! // Send messages
11//! sender.send(&data).await?;
12//! sender.send(&more_data).await?;
13//!
14//! // Wait for all to be acknowledged
15//! sender.flush().await?;
16//! ```
17//!
18//! ## Receiver Example
19//!
20//! ```ignore
21//! let mut receiver = SrsppReceiver::new(config, link);
22//!
23//! // Receive messages
24//! while let Some(message) = receiver.recv().await? {
25//! process(message);
26//! }
27//! ```
28
29/// Async SRSPP receiver.
30mod receiver;
31/// Async SRSPP sender.
32mod sender;
33#[cfg(test)]
34mod tests;
35
36pub use receiver::{DeliveryToken, SrsppReceiver};
37pub use sender::SrsppSender;
38
39use crate::transport::srspp::machine::receiver::ReceiverError;
40use crate::transport::srspp::machine::sender::SenderError;
41
42use tokio::time::Duration;
43use tokio::time::Instant;
44
45/// Error type for srspp operations.
46#[derive(Debug, thiserror::Error)]
47pub enum SrsppError {
48 /// Send buffer is full.
49 #[error("send buffer full")]
50 BufferFull,
51 /// Window is full (too many unacked packets).
52 #[error("window full")]
53 WindowFull,
54 /// Link error.
55 #[error("network error: {0}")]
56 Network(String),
57 /// Packet error.
58 #[error("packet error: {0}")]
59 PacketError(String),
60 /// Sender error.
61 #[error(transparent)]
62 SenderError(#[from] SenderError),
63 /// Receiver error.
64 #[error(transparent)]
65 ReceiverError(#[from] ReceiverError),
66}
67
68/// Converts a tick count to a `Duration` given the tick rate.
69fn ticks_to_duration(ticks: u32, ticks_per_sec: u32) -> Duration {
70 Duration::from_millis((ticks as u64 * 1000) / ticks_per_sec as u64)
71}
72
73/// Sleeps until the given deadline, or forever if `None`.
74async fn sleep_until(deadline: Option<Instant>) {
75 match deadline {
76 Some(d) => tokio::time::sleep_until(d.into()).await,
77 None => std::future::pending().await,
78 }
79}