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