use mbus_core::transport::UnitIdOrSlaveAddr;
use std::future::Future;
use super::app_handler::{AsyncAppHandler, AsyncServerError};
use super::session::AsyncServerSession;
#[cfg(feature = "server-serial")]
pub struct AsyncSerialServer<T: mbus_core::transport::AsyncTransport + Send> {
session: AsyncServerSession<T>,
}
#[cfg(feature = "server-serial")]
impl<T: mbus_core::transport::AsyncTransport + Send> AsyncSerialServer<T> {
pub async fn run<APP: AsyncAppHandler>(
&mut self,
mut app: APP,
) -> Result<(), AsyncServerError> {
self.session.run(&mut app).await
}
pub async fn run_with_shutdown<APP, F>(
&mut self,
app: APP,
shutdown: F,
) -> Result<(), AsyncServerError>
where
APP: AsyncAppHandler,
F: Future<Output = ()>,
{
let mut app = app;
tokio::select! {
biased;
_ = shutdown => Ok(()),
result = self.session.run(&mut app) => result,
}
}
pub fn from_transport(transport: T, unit: UnitIdOrSlaveAddr) -> Self {
Self {
session: AsyncServerSession::new(transport, unit),
}
}
}
#[cfg(feature = "server-serial")]
pub type AsyncRtuServer = AsyncSerialServer<mbus_serial::TokioRtuTransport>;
#[cfg(feature = "server-serial")]
pub type AsyncAsciiServer = AsyncSerialServer<mbus_serial::TokioAsciiTransport>;
#[cfg(feature = "server-serial")]
impl AsyncRtuServer {
pub fn new_rtu(
config: &mbus_core::transport::ModbusConfig,
unit: UnitIdOrSlaveAddr,
) -> Result<Self, AsyncServerError> {
let transport =
mbus_serial::TokioRtuTransport::new(config).map_err(AsyncServerError::Transport)?;
Ok(Self::from_transport(transport, unit))
}
}
#[cfg(feature = "server-serial")]
impl AsyncAsciiServer {
pub fn new_ascii(
config: &mbus_core::transport::ModbusConfig,
unit: UnitIdOrSlaveAddr,
) -> Result<Self, AsyncServerError> {
let transport =
mbus_serial::TokioAsciiTransport::new(config).map_err(AsyncServerError::Transport)?;
Ok(Self::from_transport(transport, unit))
}
}