Skip to main content

wekan_cli/commands/
boards.rs

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