Skip to main content

wekan_cli/commands/
boards.rs

1mod attachments;
2mod card_settings;
3mod copy;
4mod count;
5mod create;
6mod delete;
7mod domains;
8mod export;
9mod get;
10mod import;
11mod import_zip;
12mod labels;
13mod list;
14mod members;
15mod rename;
16
17#[cfg(test)]
18mod tests;
19
20use clap::{Args, Subcommand};
21
22use crate::{
23    client::WekanClientFactory, command_result::CommandSuccess, credentials::CredentialStore,
24    error::AppError, input::ConfirmationProvider,
25};
26
27#[derive(Debug, Args)]
28pub struct BoardArgs {
29    #[command(subcommand)]
30    pub command: BoardCommand,
31}
32
33#[derive(Debug, Subcommand)]
34pub enum BoardCommand {
35    /// List attachment links using Wekan's legacy board projection.
36    Attachment(attachments::AttachmentArgs),
37    /// Import an export document into a new board.
38    Import(import::ImportArgs),
39    /// Import a native ZIP archive into an existing board.
40    ImportZip(import_zip::ImportZipArgs),
41    /// Export a native artifact to a file or validated raw stdout.
42    Export(Box<export::ExportArgs>),
43    /// Read or update card display controls and aging thresholds.
44    CardSettings(card_settings::CardSettingsArgs),
45    /// List or request changes to email-domain sharing.
46    Domain(domains::DomainArgs),
47    /// Copy a board using Wekan's native copy operation.
48    Copy(copy::CopyArgs),
49    /// List or add reusable board labels.
50    Label(labels::LabelArgs),
51    /// List, add, remove, or change board members.
52    Member(members::MemberArgs),
53    /// List active boards for the authenticated user, or all public boards.
54    List(list::ListArgs),
55
56    /// Count all private and public boards on the server.
57    Count(count::CountArgs),
58
59    /// Show a board by ID.
60    Get(get::GetArgs),
61
62    /// Create a board and its default swimlane.
63    Create(create::CreateArgs),
64
65    /// Rename a board.
66    Rename(rename::RenameArgs),
67
68    /// Permanently delete a board and all of its contents.
69    Delete(delete::DeleteArgs),
70}
71
72pub(crate) async fn dispatch(
73    command: BoardCommand,
74    client_factory: &WekanClientFactory,
75    credential_store: &dyn CredentialStore,
76    confirmation: &dyn ConfirmationProvider,
77) -> Result<CommandSuccess, AppError> {
78    match command {
79        BoardCommand::Attachment(args) => {
80            attachments::dispatch(args.command, client_factory, credential_store).await
81        }
82        BoardCommand::Import(args) => import::execute(args, client_factory, credential_store).await,
83        BoardCommand::ImportZip(args) => {
84            import_zip::execute(args, client_factory, credential_store).await
85        }
86        BoardCommand::Export(args) => {
87            export::execute(*args, client_factory, credential_store).await
88        }
89        BoardCommand::CardSettings(args) => {
90            card_settings::dispatch(args.command, client_factory, credential_store).await
91        }
92        BoardCommand::Domain(args) => {
93            domains::dispatch(args.command, client_factory, credential_store).await
94        }
95        BoardCommand::Copy(args) => copy::execute(args, client_factory, credential_store).await,
96        BoardCommand::Label(args) => {
97            labels::dispatch(args.command, client_factory, credential_store).await
98        }
99        BoardCommand::Member(args) => {
100            members::dispatch(args.command, client_factory, credential_store).await
101        }
102        BoardCommand::List(args) => list::execute(args, client_factory, credential_store).await,
103        BoardCommand::Count(args) => count::execute(args, client_factory, credential_store).await,
104        BoardCommand::Get(args) => get::execute(args, client_factory, credential_store).await,
105        BoardCommand::Create(args) => create::execute(args, client_factory, credential_store).await,
106        BoardCommand::Rename(args) => rename::execute(args, client_factory, credential_store).await,
107        BoardCommand::Delete(args) => {
108            delete::execute(args, client_factory, credential_store, confirmation).await
109        }
110    }
111}
112
113fn non_empty(value: &str) -> Result<String, String> {
114    if value.is_empty() {
115        Err("value must not be empty".to_owned())
116    } else {
117        Ok(value.to_owned())
118    }
119}
120
121fn trimmed_non_empty(value: &str) -> Result<String, String> {
122    let value = value.trim();
123    if value.is_empty() {
124        Err("value must not be empty or whitespace".to_owned())
125    } else {
126        Ok(value.to_owned())
127    }
128}