ratel_rust/
pty.rs

1use anyhow::Result;
2use crossterm::event::{self, Event, KeyEvent};
3use tokio::io::{AsyncBufReadExt, BufReader};
4use tokio::sync::mpsc;
5
6/// Simple stdin reader that reads directly from stdin
7pub async fn read_line() -> Result<String> {
8    let stdin = tokio::io::stdin();
9    let mut reader = BufReader::new(stdin);
10    let mut line = String::new();
11    reader.read_line(&mut line).await?;
12    Ok(line.trim().to_string())
13}
14
15/// Terminal input handler using crossterm
16pub async fn read_key() -> Result<KeyEvent> {
17    loop {
18        if event::poll(std::time::Duration::from_millis(100))? {
19            if let Event::Key(key) = event::read()? {
20                return Ok(key);
21            }
22        }
23    }
24}
25
26/// PTY manager that handles I/O between the application and PTY
27pub struct PtyManager {
28    tx: mpsc::UnboundedSender<Vec<u8>>,
29    rx: mpsc::UnboundedReceiver<Vec<u8>>,
30}
31
32impl PtyManager {
33    pub fn new() -> Self {
34        let (tx, rx) = mpsc::unbounded_channel();
35        Self { tx, rx }
36    }
37
38    pub fn sender(&self) -> mpsc::UnboundedSender<Vec<u8>> {
39        self.tx.clone()
40    }
41
42    pub fn receiver(&mut self) -> &mut mpsc::UnboundedReceiver<Vec<u8>> {
43        &mut self.rx
44    }
45}
46
47impl Default for PtyManager {
48    fn default() -> Self {
49        Self::new()
50    }
51}