46 lines
1.2 KiB
Rust
46 lines
1.2 KiB
Rust
|
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(())
|
||
|
}
|