dotfiles/agent/src/services/terminal.rs

46 lines
1.2 KiB
Rust
Raw Normal View History

2024-01-29 18:18:29 +00:00
use bytes::Bytes;
use futures::Stream;
use serde::Deserialize;
use tokio::io::AsyncWriteExt;
use tokio_stream::StreamExt;
use tokio_util::codec::{BytesCodec, FramedRead};
use super::Ctx;
#[derive(Debug, Deserialize)]
pub struct OpenTerminalMessage {
id: String,
}
impl TryFrom<Bytes> for OpenTerminalMessage {
type Error = serde_json::Error;
fn try_from(value: Bytes) -> Result<Self, Self::Error> {
serde_json::from_slice(&value[..])
}
}
pub async fn open_terminal(ctx: Ctx<OpenTerminalMessage>) -> anyhow::Result<()> {
let pty = crate::pty::Pty::open()?;
let mut pty_clone = pty.try_clone()?;
tokio::spawn(async move {
while let Some(data) = tokio_stream::once(b"foo").next().await {
if let Err(err) = pty_clone.write_all(&data[..]).await {
tracing::warn!(%err, "pseudoterminal write error");
}
}
});
let _out_stream = FramedRead::new(pty, BytesCodec::new()).filter_map(|inner| {
inner
.map(|bytes| bytes.freeze())
.map_err(|err| {
tracing::warn!(%err, "pseudoterminal read error");
})
.ok()
});
Ok(())
}