use super::remember::parse_remember;
use crate::cli::{ContractsCommand, ForgetReasonArg, ReviewDecisionArg};
use crate::slash::SlashParseError;
fn usage_contracts() -> String {
"/contracts [catalog.schema.object]".into()
}
fn usage_forget() -> String {
"/forget <claim-id>".into()
}
fn usage_queue() -> String {
"/queue [limit]".into()
}
fn usage_decide() -> String {
"/confirm|/reject|/use <claim-id-prefix>".into()
}
fn usage_approve_all() -> String {
"/approve-all [--yes] [limit]".into()
}
fn parse_decide(
_name: &str,
arg: &str,
decision: ReviewDecisionArg,
) -> Result<Option<ContractsCommand>, SlashParseError> {
let tokens: Vec<&str> = arg.split_whitespace().collect();
let prefix = tokens
.first()
.ok_or_else(|| SlashParseError(usage_decide()))?;
if tokens.len() != 1 {
return Err(SlashParseError(usage_decide()));
}
Ok(Some(ContractsCommand::Decide {
prefix: prefix.to_string(),
decision,
profile: None,
}))
}
pub(crate) fn parse_contract_command(
name: &str,
arg: &str,
) -> Result<Option<ContractsCommand>, SlashParseError> {
match name {
"contracts" | "contract" => {
let tokens: Vec<&str> = arg.split_whitespace().collect();
match tokens.len() {
0 => Ok(Some(ContractsCommand::List { profile: None })),
1 => Ok(Some(ContractsCommand::Show {
table: tokens[0].to_string(),
profile: None,
})),
_ => Err(SlashParseError(usage_contracts())),
}
}
"remember" => {
let spec = parse_remember(arg)?;
Ok(Some(ContractsCommand::Remember {
table: spec.table,
kind: spec.kind,
value: spec.value,
column: spec.column,
reason: spec.reason,
profile: None,
}))
}
"forget" => {
let tokens: Vec<&str> = arg.split_whitespace().collect();
let id = tokens
.first()
.ok_or_else(|| SlashParseError(usage_forget()))?;
if tokens.len() != 1 {
return Err(SlashParseError(usage_forget()));
}
Ok(Some(ContractsCommand::Forget {
claim_id: id.to_string(),
reason: ForgetReasonArg::UserRequest,
}))
}
"queue" => {
let tokens: Vec<&str> = arg.split_whitespace().collect();
let limit = match tokens.len() {
0 => None,
1 => Some(
tokens[0]
.parse::<usize>()
.map_err(|_| SlashParseError(usage_queue()))?,
),
_ => return Err(SlashParseError(usage_queue())),
};
Ok(Some(ContractsCommand::Queue {
profile: None,
limit,
}))
}
"confirm" => parse_decide(name, arg, ReviewDecisionArg::Confirm),
"reject" => parse_decide(name, arg, ReviewDecisionArg::Reject),
"approve-all" => {
let mut yes = false;
let mut limit = None;
for token in arg.split_whitespace() {
if token == "--yes" {
if yes {
return Err(SlashParseError(usage_approve_all()));
}
yes = true;
} else if let Ok(parsed) = token.parse::<usize>() {
if limit.is_some() {
return Err(SlashParseError(usage_approve_all()));
}
limit = Some(parsed);
} else {
return Err(SlashParseError(usage_approve_all()));
}
}
Ok(Some(ContractsCommand::ApproveAll {
profile: None,
limit,
yes,
}))
}
_ => Ok(None),
}
}
#[cfg(test)]
#[path = "command_tests.rs"]
mod tests;