Skip to main content

msrt_std/
backend.rs

1//! Passive std backend adapter.
2
3use std::io::{Read, Write};
4
5use msrt::endpoint::{EngineConfig, PassiveEndpoint, PeerState};
6
7use crate::error::Result;
8use crate::event::AdapterEvent;
9use crate::io::IoState;
10
11/// Passive std backend adapter.
12#[derive(Debug)]
13pub struct StdBackend<T> {
14    io: T,
15    endpoint: PassiveEndpoint,
16    state: IoState,
17}
18
19impl<T> StdBackend<T>
20where
21    T: Read + Write,
22{
23    /// Creates a backend adapter using default MSRT config.
24    pub fn new(io: T) -> Self {
25        Self::with_config(io, EngineConfig::default())
26    }
27
28    /// Creates a backend adapter using `config`.
29    pub fn with_config(io: T, config: EngineConfig) -> Self {
30        Self {
31            io,
32            endpoint: PassiveEndpoint::new(config),
33            state: IoState::new(),
34        }
35    }
36
37    /// Returns the endpoint peer state.
38    pub fn peer_state(&self) -> PeerState {
39        self.endpoint.peer().state()
40    }
41
42    /// Returns a shared reference to the owned IO object.
43    pub const fn io(&self) -> &T {
44        &self.io
45    }
46
47    /// Returns a mutable reference to the owned IO object.
48    pub fn io_mut(&mut self) -> &mut T {
49        &mut self.io
50    }
51
52    /// Consumes the adapter and returns the owned IO object.
53    pub fn into_inner(self) -> T {
54        self.io
55    }
56
57    /// Drops the active backend session.
58    pub fn disconnect(&mut self) {
59        self.endpoint.disconnect();
60    }
61
62    /// Queues an application message.
63    pub fn send(&mut self, message: &[u8]) -> Result<bool> {
64        Ok(self.endpoint.send(message)?.is_some())
65    }
66
67    /// Reads currently available stream bytes and feeds them into MSRT.
68    ///
69    /// This method is best used with nonblocking IO. `WouldBlock` is treated as
70    /// no input.
71    pub fn receive_available(&mut self) -> Result<usize> {
72        self.state.receive_available(&mut self.io, |now_ms, bytes| {
73            self.endpoint.receive(now_ms, bytes)
74        })
75    }
76
77    /// Polls one adapter event and writes any pending transmit bytes.
78    pub fn poll(&mut self) -> Result<AdapterEvent> {
79        self.state.poll(&mut self.io, |now_ms, tx_buf| {
80            self.endpoint.poll(now_ms, tx_buf)
81        })
82    }
83
84    /// Runs `receive_available` followed by `poll`.
85    pub fn tick(&mut self) -> Result<AdapterEvent> {
86        let _ = self.receive_available()?;
87        self.poll()
88    }
89}