use anstream::ColorChoice;
use anyhow::{bail, Context as _, Result};
use camino::Utf8PathBuf;
use clap::{Args, Subcommand};
use tracing::warn;
use crate::Context;
mod aisle;
mod create;
#[derive(Debug, Args)]
#[command(args_conflicts_with_subcommands = true)]
pub struct ShoppingListArgs {
#[command(subcommand)]
command: Option<ShoppingListCommands>,
#[command(flatten)]
create_args: create::CreateArgs,
#[command(flatten)]
global_args: ShoppingListGlobalArgs,
}
#[derive(Debug, Subcommand)]
enum ShoppingListCommands {
Create(create::CreateArgs),
Aisle(aisle::ConfArgs),
}
#[derive(Debug, Args)]
struct ShoppingListGlobalArgs {
#[arg(short, long, global = true)]
aisle: Option<Utf8PathBuf>,
}
pub fn run(ctx: &Context, args: ShoppingListArgs) -> Result<()> {
let command = args
.command
.unwrap_or(ShoppingListCommands::Create(args.create_args));
let aile_path = args
.global_args
.aisle
.or_else(|| ctx.config.aisle(&ctx.base_path))
.map(|path| -> Result<(_, _)> {
let content = std::fs::read_to_string(&path).context("Failed to read aisle file")?;
Ok((path, content))
})
.transpose()?;
let aisle = if let Some((path, content)) = &aile_path {
match cooklang::aisle::parse(content) {
Ok(conf) => conf,
Err(e) => {
let stderr = std::io::stderr();
let color = anstream::AutoStream::choice(&stderr) != ColorChoice::Never;
cooklang::error::write_rich_error(&e, path.as_str(), content, color, stderr)?;
bail!("Error parsing aisle file")
}
}
} else {
warn!("No aisle file found");
Default::default()
};
match command {
ShoppingListCommands::Create(args) => create::run(ctx, aisle, args),
ShoppingListCommands::Aisle(args) => aisle::run(aisle, args),
}
}