//! `ripgrab json` — emit matches as line-delimited JSON.
//!
//! Useful for piping into `jq`, `vector`, or feeding structured data into a
//! downstream log pipeline.
use std::io;
use anyhow::Result;
use crate::cli::args::JsonArgs;
use crate::filter::{FilterSet, MatchOutcome};
use crate::render::mode::json::JsonRenderer;
use crate::source::file::FileSource;
use crate::source::Source;
pub async fn run(args: JsonArgs) -> Result<()> {
let filter = FilterSet::compile(&[], &[], None)?;
let compiled = args
.where_clause
.as_deref()
.map(crate::filter::dsl::parse_and_compile)
.transpose()?;
let stdout = io::stdout();
let mut renderer = JsonRenderer::new(stdout.lock(), args.pretty);
for path in &args.paths {
let mut src = FileSource::open(path).await?;
while let Some(item) = src.next_line().await? {
if let Some(c) = &compiled {
let mut ctx = crate::filter::dsl::EvalContext::new();
ctx.set("origin", &item.origin);
ctx.set("body", &item.line);
if !crate::filter::dsl::evaluate(c, &ctx) {
continue;
}
}
let fields = match filter.apply(&item.line) {
MatchOutcome::Plain => Vec::new(),
MatchOutcome::Fields(f) => f,
};
renderer.render_raw(
&item.origin,
&item.line,
&fields,
item.seq,
)?;
}
}
Ok(())
}