use clap::Parser as ClapParser;
use ksql::parser::Parser;
use std::env;
use std::io::{stdin, stdout, BufRead, Write};
#[derive(Debug, ClapParser)]
#[clap(version = env!("CARGO_PKG_VERSION"), author = env!("CARGO_PKG_AUTHORS"), about = env!("CARGO_PKG_DESCRIPTION"))]
pub struct Opts {
#[clap()]
pub expression: String,
#[clap()]
pub data: Option<String>,
}
fn main() -> anyhow::Result<()> {
let opts: Opts = Opts::parse();
let is_pipe = !atty::is(atty::Stream::Stdin);
let ex = Parser::parse(&opts.expression)?;
let stdout = stdout();
let mut stdout = stdout.lock();
if is_pipe {
let stdin = stdin();
let mut stdin = stdin.lock();
let mut data = Vec::new();
while stdin.read_until(b'\n', &mut data)? > 0 {
let v = ex.calculate(&data)?;
serde_json::to_writer(&mut stdout, &v)?;
let _ = stdout.write(&[b'\n'])?;
data.clear();
}
Ok(())
} else {
match opts.data {
None => Err(anyhow::anyhow!("No data provided")),
Some(data) => {
let v = ex.calculate(data.as_bytes())?;
serde_json::to_writer(&mut stdout, &v)?;
let _ = stdout.write(&[b'\n'])?;
Ok(())
}
}
}
}