1use std::io::Read;
2
3use clap::{Args, Parser, Subcommand};
4
5const HELP_TEMPLATE: &str = "\
6{before-help}{name} {version}
7{about-with-newline}{author-with-newline}
8{usage-heading} {usage}
9
10{all-args}{after-help}
11";
12
13#[derive(Parser, Debug)]
14#[command(author, version, about, long_about = None, propagate_version = true, help_template = HELP_TEMPLATE)]
15pub struct Cli {
16 #[command(subcommand)]
17 pub command: Commands,
18}
19
20#[derive(Subcommand, Debug)]
21pub enum Commands {
22 Format(FormatCommandArguments),
24
25 Verify(VerifyCommandArguments),
27
28 Init,
30
31 Completions(CompletionsCommandArguments),
33
34 CachePrune,
36}
37
38#[derive(Args, Debug)]
39pub struct FormatCommandArguments {
40 #[arg()]
42 pub input: Vec<std::path::PathBuf>,
43
44 #[arg(long, default_value_t = false)]
46 pub stdin: bool,
47
48 #[arg(long)]
50 pub config: Option<std::path::PathBuf>,
51
52 #[arg(long, default_value_t = false)]
54 pub debug: bool,
55
56 #[arg(long, value_enum)]
57 pub log_level: Option<LogLevel>,
58
59 #[arg(long)]
63 pub threads: Option<usize>,
64
65 #[arg(long, default_value_t = false)]
67 pub cache: bool,
68
69 #[arg(long)]
73 pub timeout: Option<u64>,
74}
75
76#[derive(Args, Debug)]
77pub struct VerifyCommandArguments {
78 #[arg()]
80 pub input: Vec<std::path::PathBuf>,
81
82 #[arg(long, default_value_t = false)]
84 pub stdin: bool,
85
86 #[arg(long)]
88 pub config: Option<std::path::PathBuf>,
89
90 #[arg(long, default_value_t = false)]
92 pub debug: bool,
93
94 #[arg(long, value_enum)]
95 pub log_level: Option<LogLevel>,
96
97 #[arg(long)]
101 pub threads: Option<usize>,
102
103 #[arg(long)]
107 pub timeout: Option<u64>,
108}
109
110impl From<VerifyCommandArguments> for FormatCommandArguments {
111 #[inline]
112 fn from(value: VerifyCommandArguments) -> Self {
113 Self {
114 input: value.input,
115 stdin: value.stdin,
116 config: value.config,
117 debug: value.debug,
118 log_level: value.log_level,
119 threads: value.threads,
120 timeout: value.timeout,
121 cache: false,
122 }
123 }
124}
125
126#[derive(clap::ValueEnum, Clone, Copy, PartialEq, Eq, Debug, Default)]
127pub enum LogLevel {
128 Trace,
129 #[default]
130 Debug,
131 Info,
132 Warn,
133 Error,
134 Off,
135}
136
137#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
138pub enum Shell {
139 Bash,
141
142 Elvish,
144
145 Fish,
147
148 Nushell,
150
151 PowerShell,
153
154 Zsh,
156}
157
158impl clap::ValueEnum for Shell {
159 fn value_variants<'a>() -> &'a [Self] {
160 &[
161 Self::Bash,
162 Self::Elvish,
163 Self::Fish,
164 Self::Nushell,
165 Self::PowerShell,
166 Self::Zsh,
167 ]
168 }
169
170 fn to_possible_value(&self) -> Option<clap::builder::PossibleValue> {
171 Some(match self {
172 Self::Bash => clap::builder::PossibleValue::new("bash"),
173 Self::Elvish => clap::builder::PossibleValue::new("elvish"),
174 Self::Fish => clap::builder::PossibleValue::new("fish"),
175 Self::Nushell => clap::builder::PossibleValue::new("nushell"),
176 Self::PowerShell => clap::builder::PossibleValue::new("powershell"),
177 Self::Zsh => clap::builder::PossibleValue::new("zsh"),
178 })
179 }
180}
181
182#[derive(Args, Debug)]
183pub struct CompletionsCommandArguments {
184 pub shell: Shell,
185}
186
187#[derive(Args, Debug)]
188pub struct CachePruneArguments {}
189
190#[inline]
191pub fn read_stdin() -> std::io::Result<String> {
192 let stdin = std::io::stdin();
193
194 let mut input = String::new();
195
196 stdin.lock().read_to_string(&mut input)?;
197
198 Ok(input)
199}