cuddle-v2/crates/cuddle/src/cli.rs

93 lines
2.5 KiB
Rust
Raw Normal View History

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<ValidatedState>,
}
impl Cli {
pub fn new(cuddle: Cuddle<ValidatedState>) -> Self {
let cli = clap::Command::new("cuddle").subcommand_required(true);
Self { cli, cuddle }
}
pub async fn setup(mut self) -> anyhow::Result<Self> {
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<Vec<clap::Command>> {
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::<String>("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<Vec<clap::Command>> {
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<Self> {
if let Some(_plan) = self.cuddle.state.plan.as_ref() {
// Add plan level commands
}
Ok(self)
}
}