mod archive;
mod bot_runs;
mod bulk;
mod copy;
mod count;
mod create;
mod delete;
mod export;
mod find_by_custom_field;
mod get;
mod import_ics;
mod labels;
mod list;
mod membership;
mod restore;
mod set_custom_field;
mod update;
#[cfg(test)]
mod tests;
use clap::{Args, Subcommand};
use crate::{
client::WekanClientFactory,
command_result::{CardMembershipKind, CommandSuccess},
credentials::CredentialStore,
error::AppError,
input::ConfirmationProvider,
};
#[derive(Debug, Args)]
pub struct CardArgs {
#[command(subcommand)]
pub command: CardCommand,
}
#[derive(Debug, Subcommand)]
pub enum CardCommand {
BotRun(bot_runs::BotRunArgs),
ImportIcs(import_ics::ImportIcsArgs),
Export(export::ExportArgs),
Count(count::CountArgs),
Copy(copy::CopyArgs),
Bulk(bulk::BulkArgs),
Label(labels::LabelArgs),
Member(membership::MembershipArgs),
Assignee(membership::MembershipArgs),
List(list::ListArgs),
Get(get::GetArgs),
SetCustomField(set_custom_field::SetCustomFieldArgs),
FindByCustomField(find_by_custom_field::FindByCustomFieldArgs),
Create(Box<create::CreateArgs>),
Update(Box<update::UpdateArgs>),
Archive(archive::ArchiveArgs),
Restore(restore::RestoreArgs),
Delete(delete::DeleteArgs),
}
pub(crate) async fn dispatch(
command: CardCommand,
client_factory: &WekanClientFactory,
credential_store: &dyn CredentialStore,
confirmation: &dyn ConfirmationProvider,
) -> Result<CommandSuccess, AppError> {
match command {
CardCommand::BotRun(args) => {
bot_runs::dispatch(args.command, client_factory, credential_store).await
}
CardCommand::ImportIcs(args) => {
import_ics::execute(args, client_factory, credential_store).await
}
CardCommand::Export(args) => export::execute(args, client_factory, credential_store).await,
CardCommand::Count(args) => count::execute(args, client_factory, credential_store).await,
CardCommand::Copy(args) => copy::execute(args, client_factory, credential_store).await,
CardCommand::Bulk(args) => {
bulk::dispatch(args.command, client_factory, credential_store, confirmation).await
}
CardCommand::Label(args) => {
labels::dispatch(args.command, client_factory, credential_store).await
}
CardCommand::Member(args) => {
membership::dispatch(
args.command,
CardMembershipKind::Member,
client_factory,
credential_store,
)
.await
}
CardCommand::Assignee(args) => {
membership::dispatch(
args.command,
CardMembershipKind::Assignee,
client_factory,
credential_store,
)
.await
}
CardCommand::List(args) => list::execute(args, client_factory, credential_store).await,
CardCommand::Get(args) => get::execute(args, client_factory, credential_store).await,
CardCommand::SetCustomField(args) => {
set_custom_field::execute(args, client_factory, credential_store).await
}
CardCommand::FindByCustomField(args) => {
find_by_custom_field::execute(args, client_factory, credential_store).await
}
CardCommand::Create(args) => create::execute(*args, client_factory, credential_store).await,
CardCommand::Update(args) => update::execute(*args, client_factory, credential_store).await,
CardCommand::Archive(args) => {
archive::execute(args, client_factory, credential_store).await
}
CardCommand::Restore(args) => {
restore::execute(args, client_factory, credential_store).await
}
CardCommand::Delete(args) => {
delete::execute(args, client_factory, credential_store, confirmation).await
}
}
}
fn non_empty(value: &str) -> Result<String, String> {
trimmed_non_empty(value)
}
fn trimmed_non_empty(value: &str) -> Result<String, String> {
let value = value.trim();
if value.is_empty() {
Err("value must not be empty or whitespace".to_owned())
} else {
Ok(value.to_owned())
}
}
fn date_input(value: &str) -> Result<crate::client::cards::CardDateInput, String> {
use crate::client::cards::CardDateInput;
Ok(match value.trim().parse::<serde_json::Number>() {
Ok(number) => CardDateInput::EpochMilliseconds(number),
Err(_) => CardDateInput::Text(value.to_owned()),
})
}