1pub mod admin;
2pub mod api;
3pub mod attachments;
4pub mod auth;
5pub(crate) mod authenticated;
6pub mod boards;
7pub mod cards;
8pub mod checklist_items;
9pub mod checklists;
10pub(crate) mod client_error;
11pub mod comments;
12pub(crate) mod credential_ops;
13pub mod custom_field_items;
14pub mod custom_fields;
15pub mod dependencies;
16pub(crate) mod exports;
17pub mod integrations;
18pub mod lists;
19pub mod profile;
20pub mod rules;
21pub mod swimlanes;
22mod transfer;
23pub mod users;
24
25#[cfg(test)]
26mod tests;
27
28use clap::Subcommand;
29
30#[derive(Debug, Subcommand)]
31pub enum RootCommand {
32 Admin(Box<admin::AdminArgs>),
34 Rule(rules::RuleArgs),
36 Integration(integrations::IntegrationArgs),
38 Dependency(dependencies::DependencyArgs),
40 Attachment(attachments::AttachmentArgs),
42 Api(api::ApiArgs),
44
45 Auth(auth::AuthArgs),
47
48 Profile(profile::ProfileArgs),
50
51 User(users::UserArgs),
53
54 Board(boards::BoardArgs),
56
57 List(lists::ListArgs),
59
60 Card(Box<cards::CardArgs>),
62
63 Checklist(checklists::ChecklistArgs),
65
66 Comment(comments::CommentArgs),
68
69 CustomField(custom_fields::CustomFieldArgs),
71
72 Swimlane(swimlanes::SwimlaneArgs),
74}
75
76impl RootCommand {
77 pub fn supports_raw_output(&self) -> bool {
78 matches!(self, Self::Api(_))
79 || self.export_delivery().is_some_and(|d| d.is_stdout())
80 || matches!(self, Self::Attachment(args) if args.command.download_destination().is_some_and(|d| d.is_stdout()))
81 }
82
83 pub(crate) fn export_delivery(&self) -> Option<&exports::DeliveryArgs> {
84 match self {
85 Self::Board(a) => {
86 if let boards::BoardCommand::Export(e) = &a.command {
87 Some(&e.delivery)
88 } else {
89 None
90 }
91 }
92 Self::Card(a) => {
93 if let cards::CardCommand::Export(e) = &a.command {
94 Some(&e.delivery)
95 } else {
96 None
97 }
98 }
99 Self::Attachment(a) => {
100 if let attachments::AttachmentCommand::Export(e) = &a.command {
101 Some(&e.delivery)
102 } else {
103 None
104 }
105 }
106 _ => None,
107 }
108 }
109 pub(crate) fn validate_export_input(&self) -> Result<(), crate::error::AppError> {
110 if let Self::Board(a) = self {
111 if let boards::BoardCommand::Export(e) = &a.command {
112 e.validate()?;
113 }
114 }
115 if let Some(delivery) = self.export_delivery() {
116 delivery.validate()?;
117 }
118 Ok(())
119 }
120 pub fn validate_output(
121 &self,
122 format: crate::output::OutputFormat,
123 ) -> Result<(), crate::error::AppError> {
124 self.validate_export_input()?;
125 if let Some(delivery) = self.export_delivery() {
126 delivery.validate_output(format)?;
127 }
128 if let Self::Attachment(args) = self {
129 args.command.validate_input()?;
130 if let Some(destination) = args.command.download_destination() {
131 destination.validate_output(format)?;
132 }
133 }
134 if format == crate::output::OutputFormat::Raw && !self.supports_raw_output() {
135 return Err(crate::error::AppError::invalid_input(
136 "--output raw requires api request, an export, or an attachment download with --destination -",
137 ));
138 }
139 Ok(())
140 }
141}