chore(refactor): define macro for get/delete cli commands

This commit is contained in:
Jon Seager 2026-02-02 13:00:48 +00:00
parent 6611643424
commit 3e0aa1653f
No known key found for this signature in database
5 changed files with 75 additions and 82 deletions

View file

@ -1,7 +1,7 @@
use anyhow::Result;
use clap::Args;
use serde_json::json;
use super::macros::{define_delete_command, define_get_command};
use super::print_json;
use crate::domain::ids::{BagId, RoastId};
use crate::infrastructure::client::BrewlogClient;
@ -42,16 +42,7 @@ pub async fn list_bags(client: &BrewlogClient, command: ListBagsCommand) -> Resu
print_json(&bags)
}
#[derive(Debug, Args)]
pub struct GetBagCommand {
#[arg(long)]
pub id: i64,
}
pub async fn get_bag(client: &BrewlogClient, command: GetBagCommand) -> Result<()> {
let bag = client.bags().get(BagId::new(command.id)).await?;
print_json(&bag)
}
define_get_command!(GetBagCommand, get_bag, BagId, bags);
#[derive(Debug, Args)]
pub struct UpdateBagCommand {
@ -83,19 +74,4 @@ pub async fn update_bag(client: &BrewlogClient, command: UpdateBagCommand) -> Re
print_json(&bag)
}
#[derive(Debug, Args)]
pub struct DeleteBagCommand {
#[arg(long)]
pub id: i64,
}
pub async fn delete_bag(client: &BrewlogClient, command: DeleteBagCommand) -> Result<()> {
let id = BagId::new(command.id);
client.bags().delete(id).await?;
let response = json!({
"status": "deleted",
"resource": "bag",
"id": id.into_inner(),
});
print_json(&response)
}
define_delete_command!(DeleteBagCommand, delete_bag, BagId, bags, "bag");

View file

@ -0,0 +1,65 @@
/// Macro to define a "get" command struct and handler function.
///
/// Generates a command struct with an `id: i64` field and an async function
/// that fetches the entity by ID and prints it as JSON.
///
/// # Example
/// ```ignore
/// define_get_command!(GetRoasterCommand, get_roaster, RoasterId, roasters);
/// ```
macro_rules! define_get_command {
($cmd_name:ident, $fn_name:ident, $id_type:ty, $client_method:ident) => {
#[derive(Debug, clap::Args)]
pub struct $cmd_name {
#[arg(long)]
pub id: i64,
}
pub async fn $fn_name(
client: &crate::infrastructure::client::BrewlogClient,
command: $cmd_name,
) -> anyhow::Result<()> {
let entity = client
.$client_method()
.get(<$id_type>::new(command.id))
.await?;
super::print_json(&entity)
}
};
}
/// Macro to define a "delete" command struct and handler function.
///
/// Generates a command struct with an `id: i64` field and an async function
/// that deletes the entity by ID and prints a confirmation JSON response.
///
/// # Example
/// ```ignore
/// define_delete_command!(DeleteRoasterCommand, delete_roaster, RoasterId, roasters, "roaster");
/// ```
macro_rules! define_delete_command {
($cmd_name:ident, $fn_name:ident, $id_type:ty, $client_method:ident, $resource_name:literal) => {
#[derive(Debug, clap::Args)]
pub struct $cmd_name {
#[arg(long)]
pub id: i64,
}
pub async fn $fn_name(
client: &crate::infrastructure::client::BrewlogClient,
command: $cmd_name,
) -> anyhow::Result<()> {
let id = <$id_type>::new(command.id);
client.$client_method().delete(id).await?;
let response = serde_json::json!({
"status": "deleted",
"resource": $resource_name,
"id": id.into_inner(),
});
super::print_json(&response)
}
};
}
pub(super) use define_delete_command;
pub(super) use define_get_command;

View file

@ -1,3 +1,4 @@
mod macros;
pub mod bags;
pub mod roasters;
pub mod roasts;

View file

@ -1,7 +1,7 @@
use anyhow::Result;
use clap::Args;
use serde_json::json;
use super::macros::{define_delete_command, define_get_command};
use super::print_json;
use crate::domain::ids::RoasterId;
use crate::domain::roasters::{NewRoaster, UpdateRoaster};
@ -39,16 +39,7 @@ pub async fn list_roasters(client: &BrewlogClient) -> Result<()> {
print_json(&roasters)
}
#[derive(Debug, Args)]
pub struct GetRoasterCommand {
#[arg(long)]
pub id: i64,
}
pub async fn get_roaster(client: &BrewlogClient, command: GetRoasterCommand) -> Result<()> {
let roaster = client.roasters().get(RoasterId::new(command.id)).await?;
print_json(&roaster)
}
define_get_command!(GetRoasterCommand, get_roaster, RoasterId, roasters);
#[derive(Debug, Args)]
pub struct UpdateRoasterCommand {
@ -82,19 +73,4 @@ pub async fn update_roaster(client: &BrewlogClient, command: UpdateRoasterComman
print_json(&roaster)
}
#[derive(Debug, Args)]
pub struct DeleteRoasterCommand {
#[arg(long)]
pub id: i64,
}
pub async fn delete_roaster(client: &BrewlogClient, command: DeleteRoasterCommand) -> Result<()> {
let id = RoasterId::new(command.id);
client.roasters().delete(id).await?;
let response = json!({
"status": "deleted",
"resource": "roaster",
"id": id.into_inner(),
});
print_json(&response)
}
define_delete_command!(DeleteRoasterCommand, delete_roaster, RoasterId, roasters, "roaster");

View file

@ -1,7 +1,7 @@
use anyhow::Result;
use clap::Args;
use serde_json::json;
use super::macros::{define_delete_command, define_get_command};
use super::print_json;
use crate::domain::ids::{RoastId, RoasterId};
use crate::domain::roasts::NewRoast;
@ -54,30 +54,5 @@ pub async fn list_roasts(client: &BrewlogClient, command: ListRoastsCommand) ->
print_json(&roasts)
}
#[derive(Debug, Args)]
pub struct GetRoastCommand {
#[arg(long)]
pub id: i64,
}
pub async fn get_roast(client: &BrewlogClient, command: GetRoastCommand) -> Result<()> {
let roast = client.roasts().get(RoastId::new(command.id)).await?;
print_json(&roast)
}
#[derive(Debug, Args)]
pub struct DeleteRoastCommand {
#[arg(long)]
pub id: i64,
}
pub async fn delete_roast(client: &BrewlogClient, command: DeleteRoastCommand) -> Result<()> {
let id = RoastId::new(command.id);
client.roasts().delete(id).await?;
let response = json!({
"status": "deleted",
"resource": "roast",
"id": id.into_inner(),
});
print_json(&response)
}
define_get_command!(GetRoastCommand, get_roast, RoastId, roasts);
define_delete_command!(DeleteRoastCommand, delete_roast, RoastId, roasts, "roast");