use embedded_io_async::{Read, Write};
use sunset::*;
use crate::*;
use async_channel::{ChanIn, ChanInOut};
use async_sunset::{AsyncSunset, ProgressHolder};
pub struct SSHClient<'a> {
sunset: AsyncSunset<'a, sunset::Client>,
}
impl<'a> SSHClient<'a> {
pub fn new(inbuf: &'a mut [u8], outbuf: &'a mut [u8]) -> Self {
let runner = Runner::new_client(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::Client>,
) -> Result<CliEvent<'f, 'a>> {
match self.sunset.progress(ph).await? {
Event::Cli(x) => Ok(x),
Event::None => Ok(CliEvent::PollAgain),
Event::Progressed => Ok(CliEvent::PollAgain),
_ => Error::bug(),
}
}
pub async fn open_session_nopty(&self) -> Result<(ChanInOut<'_>, ChanIn<'_>)> {
let ch =
self.sunset.with_runner(|runner| runner.open_client_session()).await?;
let io_normal = self.sunset.add_channel(ch).await?;
let e = ChanIn::new(io_normal.clone_stderr());
let i = ChanInOut::new(io_normal);
Ok((i, e))
}
pub async fn open_session_pty(&self) -> Result<ChanInOut<'_>> {
let ch =
self.sunset.with_runner(|runner| runner.open_client_session()).await?;
Ok(ChanInOut::new(self.sunset.add_channel(ch).await?))
}
}
#[cfg(feature = "alloc")]
impl SSHClient<'static> {
pub fn new_owned() -> Self {
let runner = Runner::<'static, _>::new_client_owned();
let sunset = AsyncSunset::new(runner);
Self { sunset }
}
}
#[cfg(feature = "futures-io")]
impl SSHClient<'_> {
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 SSHClient<'_> {
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
}
}