Skip to main content

wekan_cli/commands/
cards.rs

1mod archive;
2mod create;
3mod delete;
4mod get;
5mod list;
6mod restore;
7mod update;
8
9#[cfg(test)]
10mod tests;
11
12use clap::{Args, Subcommand};
13use time::{OffsetDateTime, format_description::well_known::Rfc3339};
14
15use crate::{
16    client::WekanClientFactory, command_result::CommandSuccess, credentials::CredentialStore,
17    error::AppError, input::ConfirmationProvider,
18};
19
20#[derive(Debug, Args)]
21pub struct CardArgs {
22    #[command(subcommand)]
23    pub command: CardCommand,
24}
25
26#[derive(Debug, Subcommand)]
27pub enum CardCommand {
28    /// List the cards returned by Wekan for a board list.
29    List(list::ListArgs),
30
31    /// Show one card by board, list, and card ID.
32    Get(get::GetArgs),
33
34    /// Create a card in a board list.
35    Create(Box<create::CreateArgs>),
36
37    /// Update one or more editable card fields.
38    Update(Box<update::UpdateArgs>),
39
40    /// Archive an active card and its child cards.
41    Archive(archive::ArchiveArgs),
42
43    /// Restore an archived card and its child cards.
44    Restore(restore::RestoreArgs),
45
46    /// Permanently delete a card and its child resources.
47    Delete(delete::DeleteArgs),
48}
49
50pub(crate) async fn dispatch(
51    command: CardCommand,
52    client_factory: &WekanClientFactory,
53    credential_store: &dyn CredentialStore,
54    confirmation: &dyn ConfirmationProvider,
55) -> Result<CommandSuccess, AppError> {
56    match command {
57        CardCommand::List(args) => list::execute(args, client_factory, credential_store).await,
58        CardCommand::Get(args) => get::execute(args, client_factory, credential_store).await,
59        CardCommand::Create(args) => create::execute(*args, client_factory, credential_store).await,
60        CardCommand::Update(args) => update::execute(*args, client_factory, credential_store).await,
61        CardCommand::Archive(args) => {
62            archive::execute(args, client_factory, credential_store).await
63        }
64        CardCommand::Restore(args) => {
65            restore::execute(args, client_factory, credential_store).await
66        }
67        CardCommand::Delete(args) => {
68            delete::execute(args, client_factory, credential_store, confirmation).await
69        }
70    }
71}
72
73fn non_empty(value: &str) -> Result<String, String> {
74    trimmed_non_empty(value)
75}
76
77fn trimmed_non_empty(value: &str) -> Result<String, String> {
78    let value = value.trim();
79    if value.is_empty() {
80        Err("value must not be empty or whitespace".to_owned())
81    } else {
82        Ok(value.to_owned())
83    }
84}
85
86fn rfc3339(value: &str) -> Result<String, String> {
87    OffsetDateTime::parse(value, &Rfc3339)
88        .map(|_| value.to_owned())
89        .map_err(|_| "value must be an RFC3339 date-time".to_owned())
90}