use std::{borrow::BorrowMut, io::Write}; use anyhow::anyhow; use get_command::GetCommand; use crate::{cuddle_state::Cuddle, state::ValidatedState}; mod get_command; pub struct Cli { cli: clap::Command, cuddle: Cuddle, } impl Cli { pub fn new(cuddle: Cuddle) -> Self { let cli = clap::Command::new("cuddle").subcommand_required(true); Self { cli, cuddle } } pub async fn setup(mut self) -> anyhow::Result { let commands = self.get_commands().await?; self.cli = self.cli.subcommands(commands); // TODO: Add global // TODO: Add components Ok(self) } async fn get_commands(&self) -> anyhow::Result> { Ok(vec![ clap::Command::new("do").subcommand_required(true), clap::Command::new("get") .about(GetCommand::description()) .arg( clap::Arg::new("query") .required(true) .help("query is how values are extracted, '.project.name' etc"), ), ]) } pub async fn execute(self) -> anyhow::Result<()> { match self .cli .get_matches_from(std::env::args()) .subcommand() .ok_or(anyhow::anyhow!("failed to find subcommand"))? { ("do", _args) => { tracing::debug!("executing do"); } ("get", args) => { if !self.cuddle.has_project() { anyhow::bail!("get is not available without a project"); } let query = args .get_one::("query") .ok_or(anyhow!("query is required"))?; let res = GetCommand::new(self.cuddle).execute(query).await?; std::io::stdout().write_all(res.as_bytes())?; std::io::stdout().write_all("\n".as_bytes())?; } _ => {} } Ok(()) } async fn add_project_commands(&self) -> anyhow::Result> { if let Some(_project) = self.cuddle.state.project.as_ref() { // Add project level commands return Ok(vec![]); } Ok(Vec::new()) } async fn add_plan_commands(self) -> anyhow::Result { if let Some(_plan) = self.cuddle.state.plan.as_ref() { // Add plan level commands } Ok(self) } }