//! Stdin-backed [`Source`].
//!
//! Mostly useful when piping the output of another command (`journalctl -f |
//! ripgrab --stdin`). There's no rotation or follow logic; we simply hand
//! lines out until EOF.
use anyhow::Result;
use tokio::io::{AsyncBufReadExt, BufReader};
use super::{LineItem, Source};
pub struct StdinSource {
reader: BufReader<tokio::io::Stdin>,
seq: u64,
label: String,
}
impl StdinSource {
pub fn new() -> Self {
Self {
reader: BufReader::new(tokio::io::stdin()),
seq: 0,
label: "stdin".into(),
}
}
}
impl Default for StdinSource {
fn default() -> Self {
Self::new()
}
}
#[async_trait::async_trait]
impl Source for StdinSource {
async fn next_line(&mut self) -> Result<Option<LineItem>> {
let mut line = String::new();
let read = self.reader.read_line(&mut line).await?;
if read == 0 {
return Ok(None);
}
while line.ends_with('\n') || line.ends_with('\r') {
line.pop();
}
self.seq += 1;
Ok(Some(LineItem {
line,
origin: self.label.clone(),
seq: self.seq,
}))
}
fn label(&self) -> &str {
&self.label
}
}