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 for OpenTerminalMessage { type Error = serde_json::Error; fn try_from(value: Bytes) -> Result { serde_json::from_slice(&value[..]) } } pub async fn open_terminal(ctx: Ctx) -> 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(()) }