remowt-client 0.1.9

russh-based client connection to a remowt agent
Documentation
use anyhow::{anyhow, Result};
use bifrostlink::declarative::RemoteEndpoints as _;
use bifrostlink::Remote;
use remowt_endpoints::pty::{PtyClient, ShellId};
use remowt_link_shared::{Address, BifConfig};

use crate::forwarded::RemowtStream;
use crate::Remowt;

pub struct RemowtShell {
	pub id: ShellId,
	pub stream: RemowtStream,
	remote: Remote<BifConfig>,
}
impl RemowtShell {
	pub fn resizer(&self) -> RemowtShellResizer {
		RemowtShellResizer {
			remote: self.remote.clone(),
			id: self.id,
		}
	}
}

#[derive(Clone)]
pub struct RemowtShellResizer {
	remote: Remote<BifConfig>,
	id: ShellId,
}

impl RemowtShellResizer {
	pub async fn resize(&self, cols: u16, rows: u16) -> Result<()> {
		PtyClient::wrap(self.remote.clone())
			.resize(self.id, cols, rows)
			.await?
			.map_err(|e| anyhow!("failed to resize remote shell: {e}"))
	}
}

impl Remowt {
	pub async fn open_shell(
		&self,
		term: &str,
		cols: u16,
		rows: u16,
		escalate: bool,
	) -> Result<RemowtShell> {
		let (forwarded, path) = self.bind_runtime_unix("shell").await?;
		let client: PtyClient<BifConfig> = if escalate {
			self.run0_endpoints().await?
		} else {
			self.endpoints()
		};
		let id = client
			.open_shell(path, term.to_owned(), cols, rows)
			.await?
			.map_err(|e| anyhow!("agent failed to open shell: {e}"))?;
		let stream = forwarded.accept().await?;

		Ok(RemowtShell {
			id,
			stream,
			remote: self.0.rpc.remote(Address::Agent),
		})
	}
}