use std::io::Write;
use anyhow::{Context, Result};
use doiget_core::store::{FsStore, Store};
use super::resolve_store_root;
const DEFAULT_LIMIT: usize = 50;
const FETCHED_AT_FMT: &str = "%Y-%m-%dT%H:%M:%SZ";
pub fn run(query: String, mode: super::output::OutputMode) -> Result<()> {
if query.trim().is_empty() {
anyhow::bail!("search query is empty");
}
let store_root = resolve_store_root()?;
let store = FsStore::new(store_root)?;
let entries = store
.search(&query, DEFAULT_LIMIT)
.with_context(|| format!("search failed for query {query:?}"))?;
if mode == super::output::OutputMode::Quiet {
return Ok(());
}
let stdout = std::io::stdout();
let mut out = stdout.lock();
if mode == super::output::OutputMode::Json {
let s = serde_json::to_string_pretty(&entries)
.context("failed to serialize search entries to JSON")?;
writeln!(out, "{s}").context("failed to write search JSON to stdout")?;
return Ok(());
}
writeln!(out, "safekey\tyear\ttitle\tfetched_at")
.context("failed to write search header to stdout")?;
for e in entries {
let year = e.year.map(|y| y.to_string()).unwrap_or_else(|| "-".into());
let fetched = e
.fetched_at
.map(|t| t.format(FETCHED_AT_FMT).to_string())
.unwrap_or_else(|| "-".into());
writeln!(
out,
"{}\t{}\t{}\t{}",
e.safekey.as_str(),
year,
e.title,
fetched
)
.context("failed to write search row to stdout")?;
}
Ok(())
}