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