use std::io::BufRead;
use tokio::sync::mpsc;
use super::{AckToken, EventSource, RawEvent};
pub struct StdinSource {
rx: mpsc::Receiver<String>,
}
impl Default for StdinSource {
fn default() -> Self {
Self::new()
}
}
impl StdinSource {
pub fn new() -> Self {
let (tx, rx) = mpsc::channel(1024);
std::thread::Builder::new()
.name("rsigma-stdin".to_string())
.spawn(move || {
let stdin = std::io::stdin();
for line in stdin.lock().lines() {
match line {
Ok(line) => {
if tx.blocking_send(line).is_err() {
break;
}
}
Err(e) => {
tracing::warn!(error = %e, "Error reading stdin");
break;
}
}
}
})
.expect("failed to spawn stdin reader thread");
StdinSource { rx }
}
}
impl EventSource for StdinSource {
async fn recv(&mut self) -> Option<RawEvent> {
loop {
match self.rx.recv().await {
Some(line) if !line.trim().is_empty() => {
return Some(RawEvent {
payload: line,
ack_token: AckToken::Noop,
});
}
Some(_) => continue,
None => return None,
}
}
}
}