use embedded_io_async::{Read, Write};
use sunset::*;
use crate::*;
use async_sunset::{AsyncSunset, ProgressHolder};
#[derive(Debug)]
pub struct SSHServer<'a> {
sunset: AsyncSunset<'a, sunset::Server>,
}
impl<'a> SSHServer<'a> {
pub fn new(inbuf: &'a mut [u8], outbuf: &'a mut [u8]) -> Self {
let runner = Runner::new_server(inbuf, outbuf);
let sunset = AsyncSunset::new(runner);
Self { sunset }
}
pub async fn run(
&self,
rsock: &mut impl Read,
wsock: &mut impl Write,
) -> Result<()> {
self.sunset.run(rsock, wsock).await
}
pub async fn progress<'g, 'f>(
&'g self,
ph: &'f mut ProgressHolder<'g, 'a, sunset::Server>,
) -> Result<ServEvent<'f, 'a>> {
match self.sunset.progress(ph).await? {
Event::Serv(x) => Ok(x),
Event::None => Ok(ServEvent::PollAgain),
Event::Progressed => Ok(ServEvent::PollAgain),
Event::Cli(_) => Error::bug(),
}
}
pub async fn stdio(&self, ch: ChanHandle) -> Result<ChanInOut<'_>> {
Ok(ChanInOut::new(self.sunset.add_channel(ch).await?))
}
pub async fn stdio_stderr(
&self,
ch: ChanHandle,
) -> Result<(ChanInOut<'_>, ChanOut<'_>)> {
let io_normal = self.sunset.add_channel(ch).await?;
let e = ChanOut::new(io_normal.clone_stderr());
let i = ChanInOut::new(io_normal);
Ok((i, e))
}
}
#[cfg(feature = "alloc")]
impl SSHServer<'static> {
pub fn new_owned() -> Self {
let runner = Runner::new_server_owned();
let sunset = AsyncSunset::new(runner);
Self { sunset }
}
}
#[cfg(feature = "futures-io")]
impl SSHServer<'_> {
pub async fn run_futures_io(
&self,
rsock: &mut (impl futures_io::AsyncRead + Unpin),
wsock: &mut (impl futures_io::AsyncWrite + Unpin),
) -> Result<()> {
let mut rsock = embedded_io_adapters::futures_03::FromFutures::new(rsock);
let mut wsock = embedded_io_adapters::futures_03::FromFutures::new(wsock);
self.sunset.run(&mut rsock, &mut wsock).await
}
}
#[cfg(feature = "tokio")]
impl SSHServer<'_> {
pub async fn run_tokio(
&self,
rsock: &mut (impl tokio::io::AsyncRead + Unpin),
wsock: &mut (impl tokio::io::AsyncWrite + Unpin),
) -> Result<()> {
let mut rsock = embedded_io_adapters::tokio_1::FromTokio::new(rsock);
let mut wsock = embedded_io_adapters::tokio_1::FromTokio::new(wsock);
self.sunset.run(&mut rsock, &mut wsock).await
}
}