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}