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