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(crate) mod imports;
18pub mod integrations;
19pub mod lists;
20pub mod profile;
21pub mod rules;
22pub mod swimlanes;
23mod transfer;
24pub mod users;
25
26#[cfg(test)]
27mod tests;
28
29use clap::Subcommand;
30
31#[derive(Debug, Subcommand)]
32pub enum RootCommand {
33 Admin(Box<admin::AdminArgs>),
35 Rule(rules::RuleArgs),
37 Integration(integrations::IntegrationArgs),
39 Dependency(dependencies::DependencyArgs),
41 Attachment(attachments::AttachmentArgs),
43 Api(api::ApiArgs),
45
46 Auth(auth::AuthArgs),
48
49 Profile(profile::ProfileArgs),
51
52 User(users::UserArgs),
54
55 Board(boards::BoardArgs),
57
58 List(lists::ListArgs),
60
61 Card(Box<cards::CardArgs>),
63
64 Checklist(checklists::ChecklistArgs),
66
67 Comment(comments::CommentArgs),
69
70 CustomField(custom_fields::CustomFieldArgs),
72
73 Swimlane(swimlanes::SwimlaneArgs),
75}
76
77impl RootCommand {
78 pub fn supports_raw_output(&self) -> bool {
79 matches!(self, Self::Api(_))
80 || self.export_delivery().is_some_and(|d| d.is_stdout())
81 || matches!(self, Self::Attachment(args) if args.command.download_destination().is_some_and(|d| d.is_stdout()))
82 }
83
84 pub(crate) fn export_delivery(&self) -> Option<&exports::DeliveryArgs> {
85 match self {
86 Self::Board(a) => {
87 if let boards::BoardCommand::Export(e) = &a.command {
88 Some(&e.delivery)
89 } else {
90 None
91 }
92 }
93 Self::Card(a) => {
94 if let cards::CardCommand::Export(e) = &a.command {
95 Some(&e.delivery)
96 } else {
97 None
98 }
99 }
100 Self::Attachment(a) => {
101 if let attachments::AttachmentCommand::Export(e) = &a.command {
102 Some(&e.delivery)
103 } else {
104 None
105 }
106 }
107 _ => None,
108 }
109 }
110 pub(crate) fn validate_input(&self) -> Result<(), crate::error::AppError> {
111 if let Self::Board(a) = self {
112 if let boards::BoardCommand::Import(args) = &a.command {
113 args.validate()?;
114 }
115 }
116 if let Self::Board(a) = self {
117 if let boards::BoardCommand::Export(e) = &a.command {
118 e.validate()?;
119 }
120 }
121 if let Some(delivery) = self.export_delivery() {
122 delivery.validate()?;
123 }
124 Ok(())
125 }
126 pub fn validate_output(
127 &self,
128 format: crate::output::OutputFormat,
129 ) -> Result<(), crate::error::AppError> {
130 self.validate_input()?;
131 if let Some(delivery) = self.export_delivery() {
132 delivery.validate_output(format)?;
133 }
134 if let Self::Attachment(args) = self {
135 args.command.validate_input()?;
136 if let Some(destination) = args.command.download_destination() {
137 destination.validate_output(format)?;
138 }
139 }
140 if format == crate::output::OutputFormat::Raw && !self.supports_raw_output() {
141 return Err(crate::error::AppError::invalid_input(
142 "--output raw requires api request, an export, or an attachment download with --destination -",
143 ));
144 }
145 Ok(())
146 }
147}