use clap::Subcommand;
use serde_json::json;
use crate::connect::Broker;
use crate::context::Settings;
use crate::error::{Exit, fail};
use crate::output::Output;
#[derive(Debug, Subcommand)]
pub(crate) enum CounterCommand {
#[command(
long_about = "Print a counter's sum. Exits with status 5 when it has never been \
written.",
after_long_help = "Examples:
felixctl counter get stats page-views
felixctl counter get stats page-views --json"
)]
Get {
cache: String,
key: String,
},
#[command(
long_about = "Add DELTA, which may be negative, to a counter and print its sum \
including the add. A counter that has never been written starts \
at zero. The add is sent once: a failure is not retried, since the \
broker may already have applied it.",
after_long_help = "Examples:
felixctl counter add stats page-views 1
felixctl counter add stats stock -3"
)]
Add {
cache: String,
key: String,
#[arg(allow_negative_numbers = true)]
delta: i64,
},
}
pub(crate) async fn run(
command: &CounterCommand,
settings: &Settings,
out: &Output,
) -> anyhow::Result<()> {
let broker = Broker::connect(settings).await?;
let (tenant, namespace) = (broker.tenant.as_str(), broker.namespace.as_str());
match command {
CounterCommand::Get { cache, key } => {
let Some(sum) = broker
.cluster
.counter_get(tenant, namespace, cache, key)
.await?
else {
return Err(fail(
Exit::NotFound,
format!("counter {cache}/{key} is not set"),
));
};
out.done(
&sum.to_string(),
json!({ "cache": cache, "key": key, "value": sum }),
)
}
CounterCommand::Add { cache, key, delta } => {
let sum = broker
.cluster
.counter_add(tenant, namespace, cache, key, *delta)
.await?;
out.done(
&sum.to_string(),
json!({ "cache": cache, "key": key, "delta": delta, "value": sum }),
)
}
}
}