dstar_gateway_core/session/
driver.rs

1//! Sans-io `Driver` trait.
2
3use std::net::SocketAddr;
4use std::time::Instant;
5
6/// One outbound datagram from the sans-io core.
7#[derive(Debug, Clone)]
8pub struct Transmit<'a> {
9    /// Destination address.
10    pub dst: SocketAddr,
11    /// Wire bytes (borrowed from the session's internal scratch buffer).
12    pub payload: &'a [u8],
13}
14
15impl<'a> Transmit<'a> {
16    /// Construct a transmit from a destination + borrowed payload.
17    #[must_use]
18    pub const fn new(dst: SocketAddr, payload: &'a [u8]) -> Self {
19        Self { dst, payload }
20    }
21}
22
23/// Sans-io driver. Mirrors `quinn-proto::Connection` and
24/// `rustls::Connection`.
25///
26/// The shell calls these methods in a loop. The core never calls
27/// back into the shell. **Time is injected via the `now: Instant`
28/// parameter on every call** — implementors of this trait must NOT
29/// consult `Instant::now()` themselves.
30pub trait Driver {
31    /// Consumer-visible event type.
32    type Event;
33    /// Per-protocol structured error type.
34    type Error;
35
36    /// Feed an inbound datagram. Parses, advances state, may push
37    /// events / outbound packets / timer updates.
38    ///
39    /// # Errors
40    ///
41    /// Returns the protocol-specific error if the bytes cannot be
42    /// parsed.
43    fn handle_input(
44        &mut self,
45        now: Instant,
46        peer: SocketAddr,
47        bytes: &[u8],
48    ) -> Result<(), Self::Error>;
49
50    /// Tell the core that wall time has advanced.
51    fn handle_timeout(&mut self, now: Instant);
52
53    /// Pop the next outbound datagram, if any.
54    fn poll_transmit(&mut self, now: Instant) -> Option<Transmit<'_>>;
55
56    /// Pop the next consumer-visible event.
57    fn poll_event(&mut self) -> Option<Self::Event>;
58
59    /// Earliest instant at which the core needs to be re-entered.
60    ///
61    /// `None` means "no pending timer — only wake me on input".
62    fn poll_timeout(&self) -> Option<Instant>;
63}
64
65#[cfg(test)]
66mod tests {
67    use super::*;
68    use std::net::{IpAddr, Ipv4Addr};
69
70    const ADDR: SocketAddr = SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), 30001);
71
72    #[test]
73    fn transmit_new_constructs() {
74        let payload: &[u8] = &[0x05, 0x00, 0x18, 0x00, 0x01];
75        let tx = Transmit::new(ADDR, payload);
76        assert_eq!(tx.dst, ADDR);
77        assert_eq!(tx.payload, payload);
78    }
79}