use clap::Parser;
use flarer::cli::{Args, InteractiveConfig, interactive_init, interactive_prompt};
use flarer::{Account, Flarer, JsonOptions, Output, ResponseFormat, Tool};
use tracing_subscriber::{EnvFilter, fmt};
#[tokio::main]
async fn main() {
init_tracing();
if let Err(err) = run().await {
eprintln!("error: {err}");
std::process::exit(1);
}
}
fn init_tracing() {
let filter = EnvFilter::try_from_env("FLARER_LOG").unwrap_or_else(|_| EnvFilter::new("warn"));
let _ = fmt().with_env_filter(filter).with_target(false).try_init();
}
async fn run() -> flarer::Result<()> {
let raw: Vec<String> = std::env::args().collect();
let interactive_flag = raw.len() == 1 || raw.iter().any(|a| a == "-i" || a == "--interactive");
if interactive_flag {
let _ = dotenv::dotenv();
let flarer = interactive_init().await?;
let cfg = interactive_prompt().await?;
let out = run_config(&flarer, cfg).await?;
println!("{}", out.display_string());
return Ok(());
}
let args = Args::parse();
let _ = dotenv::dotenv();
let account = Account::from_env()?;
let mut builder = Flarer::builder().account(account);
if let Some(dir) = args.output_dir.clone() {
builder = builder.output_dir(dir);
}
let flarer = builder.build()?;
flarer.verify().await?;
let url = args
.url
.as_deref()
.ok_or_else(|| flarer::FlarerError::Config("--url is required".into()))?;
let out = match args.tool {
Tool::Json => {
let mut opts = JsonOptions::new();
if let Some(p) = args.prompt.clone() {
opts = opts.with_prompt(p);
}
if let Some(path) = args.schema.as_deref() {
let raw = std::fs::read_to_string(path)?;
let rf: ResponseFormat = serde_json::from_str(&raw)?;
opts = opts.with_response_format(rf);
}
Output::Json(flarer.json(url, opts).await?)
}
other => flarer.run(other, url).await?,
};
println!("{}", out.display_string());
Ok(())
}
async fn run_config(flarer: &Flarer, cfg: InteractiveConfig) -> flarer::Result<Output> {
match cfg.tool {
Tool::Json => Ok(Output::Json(flarer.json(&cfg.url, cfg.json_options).await?)),
other => flarer.run(other, &cfg.url).await,
}
}