wekan_cli/commands/
cards.rs1mod archive;
2mod create;
3mod delete;
4mod find_by_custom_field;
5mod get;
6mod list;
7mod membership;
8mod restore;
9mod set_custom_field;
10mod update;
11
12#[cfg(test)]
13mod tests;
14
15use clap::{Args, Subcommand};
16
17use crate::{
18 client::WekanClientFactory,
19 command_result::{CardMembershipKind, CommandSuccess},
20 credentials::CredentialStore,
21 error::AppError,
22 input::ConfirmationProvider,
23};
24
25#[derive(Debug, Args)]
26pub struct CardArgs {
27 #[command(subcommand)]
28 pub command: CardCommand,
29}
30
31#[derive(Debug, Subcommand)]
32pub enum CardCommand {
33 Member(membership::MembershipArgs),
35 Assignee(membership::MembershipArgs),
37 List(list::ListArgs),
39
40 Get(get::GetArgs),
42
43 SetCustomField(set_custom_field::SetCustomFieldArgs),
45 FindByCustomField(find_by_custom_field::FindByCustomFieldArgs),
47 Create(Box<create::CreateArgs>),
49
50 Update(Box<update::UpdateArgs>),
52
53 Archive(archive::ArchiveArgs),
55
56 Restore(restore::RestoreArgs),
58
59 Delete(delete::DeleteArgs),
61}
62
63pub(crate) async fn dispatch(
64 command: CardCommand,
65 client_factory: &WekanClientFactory,
66 credential_store: &dyn CredentialStore,
67 confirmation: &dyn ConfirmationProvider,
68) -> Result<CommandSuccess, AppError> {
69 match command {
70 CardCommand::Member(args) => {
71 membership::dispatch(
72 args.command,
73 CardMembershipKind::Member,
74 client_factory,
75 credential_store,
76 )
77 .await
78 }
79 CardCommand::Assignee(args) => {
80 membership::dispatch(
81 args.command,
82 CardMembershipKind::Assignee,
83 client_factory,
84 credential_store,
85 )
86 .await
87 }
88 CardCommand::List(args) => list::execute(args, client_factory, credential_store).await,
89 CardCommand::Get(args) => get::execute(args, client_factory, credential_store).await,
90 CardCommand::SetCustomField(args) => {
91 set_custom_field::execute(args, client_factory, credential_store).await
92 }
93 CardCommand::FindByCustomField(args) => {
94 find_by_custom_field::execute(args, client_factory, credential_store).await
95 }
96 CardCommand::Create(args) => create::execute(*args, client_factory, credential_store).await,
97 CardCommand::Update(args) => update::execute(*args, client_factory, credential_store).await,
98 CardCommand::Archive(args) => {
99 archive::execute(args, client_factory, credential_store).await
100 }
101 CardCommand::Restore(args) => {
102 restore::execute(args, client_factory, credential_store).await
103 }
104 CardCommand::Delete(args) => {
105 delete::execute(args, client_factory, credential_store, confirmation).await
106 }
107 }
108}
109
110fn non_empty(value: &str) -> Result<String, String> {
111 trimmed_non_empty(value)
112}
113
114fn trimmed_non_empty(value: &str) -> Result<String, String> {
115 let value = value.trim();
116 if value.is_empty() {
117 Err("value must not be empty or whitespace".to_owned())
118 } else {
119 Ok(value.to_owned())
120 }
121}
122
123fn date_input(value: &str) -> Result<crate::client::cards::CardDateInput, String> {
124 use crate::client::cards::CardDateInput;
125 Ok(match value.trim().parse::<serde_json::Number>() {
126 Ok(number) => CardDateInput::EpochMilliseconds(number),
127 Err(_) => CardDateInput::Text(value.to_owned()),
128 })
129}