1use embedded_io_async::{Read, Write};
2
3use sunset::*;
4
5use crate::*;
6use async_channel::{ChanIn, ChanInOut};
7use async_sunset::{AsyncSunset, ProgressHolder};
8use sunset::ChanData;
9
10pub struct SSHClient<'a> {
20 sunset: AsyncSunset<'a, sunset::Client>,
21}
22
23impl<'a> SSHClient<'a> {
24 pub fn new(inbuf: &'a mut [u8], outbuf: &'a mut [u8]) -> Self {
25 let runner = Runner::new_client(inbuf, outbuf);
26 let sunset = AsyncSunset::new(runner);
27 Self { sunset }
28 }
29
30 pub async fn run(
34 &self,
35 rsock: &mut impl Read,
36 wsock: &mut impl Write,
37 ) -> Result<()> {
38 self.sunset.run(rsock, wsock).await
39 }
40
41 pub async fn progress<'g, 'f>(
47 &'g self,
48 ph: &'f mut ProgressHolder<'g, 'a, sunset::Client>,
49 ) -> Result<CliEvent<'f, 'a>> {
50 match self.sunset.progress(ph).await? {
51 Event::Cli(x) => Ok(x),
52 Event::None => return Ok(CliEvent::PollAgain),
53 Event::Progressed => Ok(CliEvent::PollAgain),
54 _ => Err(Error::bug()),
55 }
56 }
57
58 pub async fn open_session_nopty(&self) -> Result<(ChanInOut<'_>, ChanIn<'_>)> {
59 let chan =
60 self.sunset.with_runner(|runner| runner.open_client_session()).await?;
61
62 let num = chan.num();
63 self.sunset.add_channel(chan, 2).await?;
64
65 let cstd = ChanInOut::new(num, ChanData::Normal, &self.sunset);
66 let cerr = ChanIn::new(num, ChanData::Stderr, &self.sunset);
67 Ok((cstd, cerr))
68 }
69
70 pub async fn open_session_pty(&self) -> Result<ChanInOut<'_>> {
71 let chan =
72 self.sunset.with_runner(|runner| runner.open_client_session()).await?;
73
74 let num = chan.num();
75 self.sunset.add_channel(chan, 1).await?;
76 let cstd = ChanInOut::new(num, ChanData::Normal, &self.sunset);
77 Ok(cstd)
78 }
79}