ratman_netmod/endpoint.rs
1//! Endpoint abstraction module
2
3use crate::{Frame, Result, Target};
4use async_trait::async_trait;
5use std::sync::Arc;
6
7/// The main trait describing a Ratman networking interface
8///
9/// All functions work without mutability because an endpoint is
10/// expected to implement some access multiplexing or rely on atomic
11/// operations to ensure thread safety. This is because it's not
12/// reasonable for an endpoint driver to rely purely on Rust's
13/// ownership and mutability model, because it will inevitably have to
14/// interact with system components, other buffers that push into a
15/// queue, or similar.
16///
17/// This interface doesn't care about the implementation details of
18/// these endpoints, and so, to make matters simpler for the router,
19/// and to make it obvious that internal mutability needs to be used,
20/// this interface is immutable by default.
21#[async_trait]
22pub trait Endpoint {
23 /// Return a desired frame size in bytes
24 ///
25 /// A user of this library should use this metric to slice larger
26 /// payloads into frame sequencies via the provided utilities.
27 ///
28 /// This metric is only a hint, and a router can choose to ignore
29 /// it, if it then deals with possible "too large" errors during
30 /// sending. Choosing between a greedy or cautious approach to
31 /// data slicing is left to the user of the interfaces.
32 fn size_hint(&self) -> usize;
33
34 /// Dispatch a `Frame` across this link
35 ///
36 /// Sending characteristics are entirely up to the implementation.
37 /// As mentioned in the `size_hint()` documentation, this function
38 /// **must not** panic on a `Frame` for size reasons, instead it
39 /// should return `Error::FrameTooLarge`.
40 ///
41 /// The target ID is a way to instruct a netmod where to send a
42 /// frame in a one-to-many mapping. When implementing a
43 /// one-to-one endpoint, this ID can be ignored (set to 0).
44 async fn send(&self, frame: Frame, target: Target) -> Result<()>;
45
46 /// Poll for the next available Frame from this interface
47 ///
48 /// It's recommended to return transmission errors, even if there
49 /// are no ways to correct the situation from the router's POV,
50 /// simply to feed packet drop metrics.
51 async fn next(&self) -> Result<(Frame, Target)>;
52}
53
54#[async_trait]
55impl<T: Endpoint + Send + Sync> Endpoint for Arc<T> {
56 fn size_hint(&self) -> usize {
57 T::size_hint(self)
58 }
59
60 async fn send(&self, frame: Frame, target: Target) -> Result<()> {
61 T::send(self, frame, target).await
62 }
63
64 async fn next(&self) -> Result<(Frame, Target)> {
65 T::next(self).await
66 }
67}