pty_output_demo/
pty_output_demo.rs

1//! Demo: TUI running `ls -la` with live PTY output
2//!
3//! Run with: cargo run --example pty_output_demo
4
5use ralph_adapters::pty_handle::PtyHandle;
6use ralph_tui::Tui;
7use std::process::Stdio;
8use tokio::io::AsyncReadExt;
9use tokio::process::Command;
10use tokio::sync::{mpsc, watch};
11
12#[tokio::main]
13async fn main() -> anyhow::Result<()> {
14    // Spawn ls -la command
15    let mut child = Command::new("ls")
16        .arg("-la")
17        .stdout(Stdio::piped())
18        .stderr(Stdio::piped())
19        .spawn()?;
20
21    let stdout = child.stdout.take().expect("Failed to capture stdout");
22    let stderr = child.stderr.take().expect("Failed to capture stderr");
23
24    // Create channels for PTY handle
25    let (output_tx, output_rx) = mpsc::unbounded_channel();
26    let (input_tx, _input_rx) = mpsc::unbounded_channel();
27    let (control_tx, _control_rx) = mpsc::unbounded_channel();
28    let (_terminated_tx, terminated_rx) = watch::channel(false);
29
30    // Clone output_tx before moving it
31    let output_tx_clone = output_tx.clone();
32
33    // Spawn task to read stdout and send to output channel
34    tokio::spawn(async move {
35        let mut stdout = stdout;
36        let mut buf = vec![0u8; 1024];
37        while let Ok(n) = stdout.read(&mut buf).await {
38            if n == 0 {
39                break;
40            }
41            let _ = output_tx.send(buf[..n].to_vec());
42        }
43    });
44
45    // Spawn task to read stderr and send to output channel
46    tokio::spawn(async move {
47        let mut stderr = stderr;
48        let mut buf = vec![0u8; 1024];
49        while let Ok(n) = stderr.read(&mut buf).await {
50            if n == 0 {
51                break;
52            }
53            let _ = output_tx_clone.send(buf[..n].to_vec());
54        }
55    });
56
57    // Create PTY handle
58    let pty_handle = PtyHandle {
59        output_rx,
60        input_tx,
61        control_tx,
62        terminated_rx,
63    };
64
65    // Create TUI with PTY handle
66    let tui = Tui::new().with_pty(pty_handle);
67
68    // Run TUI (will exit on Ctrl+C)
69    tui.run().await?;
70
71    // Wait for command to finish
72    let _ = child.wait().await;
73
74    Ok(())
75}