aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_lsp_server/src/args.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_lsp_server/src/args.rs')
-rw-r--r--crates/ra_lsp_server/src/args.rs237
1 files changed, 237 insertions, 0 deletions
diff --git a/crates/ra_lsp_server/src/args.rs b/crates/ra_lsp_server/src/args.rs
new file mode 100644
index 000000000..41959797c
--- /dev/null
+++ b/crates/ra_lsp_server/src/args.rs
@@ -0,0 +1,237 @@
1use anyhow::{bail, Result};
2use pico_args::Arguments;
3use ra_lsp_server::cli::{BenchWhat, Position, Verbosity};
4
5use std::{fmt::Write, path::PathBuf};
6
7pub(crate) struct Args {
8 pub(crate) verbosity: Verbosity,
9 pub(crate) command: Command,
10}
11
12pub(crate) enum Command {
13 Parse {
14 no_dump: bool,
15 },
16 Symbols,
17 Highlight {
18 rainbow: bool,
19 },
20 Stats {
21 randomize: bool,
22 memory_usage: bool,
23 only: Option<String>,
24 with_deps: bool,
25 path: PathBuf,
26 },
27 Bench {
28 path: PathBuf,
29 what: BenchWhat,
30 },
31 RunServer,
32 Version,
33}
34
35impl Args {
36 pub(crate) fn parse() -> Result<Result<Args, HelpPrinted>> {
37 let mut matches = Arguments::from_env();
38
39 if matches.contains("--version") {
40 matches.finish().or_else(handle_extra_flags)?;
41 return Ok(Ok(Args { verbosity: Verbosity::Normal, command: Command::Version }));
42 }
43
44 let verbosity = match (
45 matches.contains(["-vv", "--spammy"]),
46 matches.contains(["-v", "--verbose"]),
47 matches.contains(["-q", "--quiet"]),
48 ) {
49 (true, _, true) => bail!("Invalid flags: -q conflicts with -vv"),
50 (true, _, false) => Verbosity::Spammy,
51 (false, false, false) => Verbosity::Normal,
52 (false, false, true) => Verbosity::Quiet,
53 (false, true, false) => Verbosity::Verbose,
54 (false, true, true) => bail!("Invalid flags: -q conflicts with -v"),
55 };
56
57 let subcommand = match matches.subcommand()? {
58 Some(it) => it,
59 None => {
60 matches.finish().or_else(handle_extra_flags)?;
61 return Ok(Ok(Args { verbosity, command: Command::RunServer }));
62 }
63 };
64 let command = match subcommand.as_str() {
65 "parse" => {
66 if matches.contains(["-h", "--help"]) {
67 eprintln!(
68 "\
69ra-cli-parse
70
71USAGE:
72 ra_cli parse [FLAGS]
73
74FLAGS:
75 -h, --help Prints help inforamtion
76 --no-dump"
77 );
78 return Ok(Err(HelpPrinted));
79 }
80
81 let no_dump = matches.contains("--no-dump");
82 matches.finish().or_else(handle_extra_flags)?;
83 Command::Parse { no_dump }
84 }
85 "symbols" => {
86 if matches.contains(["-h", "--help"]) {
87 eprintln!(
88 "\
89ra-cli-symbols
90
91USAGE:
92 ra_cli highlight [FLAGS]
93
94FLAGS:
95 -h, --help Prints help inforamtion"
96 );
97 return Ok(Err(HelpPrinted));
98 }
99
100 matches.finish().or_else(handle_extra_flags)?;
101
102 Command::Symbols
103 }
104 "highlight" => {
105 if matches.contains(["-h", "--help"]) {
106 eprintln!(
107 "\
108ra-cli-highlight
109
110USAGE:
111 ra_cli highlight [FLAGS]
112
113FLAGS:
114 -h, --help Prints help information
115 -r, --rainbow"
116 );
117 return Ok(Err(HelpPrinted));
118 }
119
120 let rainbow = matches.contains(["-r", "--rainbow"]);
121 matches.finish().or_else(handle_extra_flags)?;
122 Command::Highlight { rainbow }
123 }
124 "analysis-stats" => {
125 if matches.contains(["-h", "--help"]) {
126 eprintln!(
127 "\
128ra-cli-analysis-stats
129
130USAGE:
131 ra_cli analysis-stats [FLAGS] [OPTIONS] [PATH]
132
133FLAGS:
134 -h, --help Prints help information
135 --memory-usage
136 -v, --verbose
137 -q, --quiet
138
139OPTIONS:
140 -o <ONLY>
141
142ARGS:
143 <PATH>"
144 );
145 return Ok(Err(HelpPrinted));
146 }
147
148 let randomize = matches.contains("--randomize");
149 let memory_usage = matches.contains("--memory-usage");
150 let only: Option<String> = matches.opt_value_from_str(["-o", "--only"])?;
151 let with_deps: bool = matches.contains("--with-deps");
152 let path = {
153 let mut trailing = matches.free()?;
154 if trailing.len() != 1 {
155 bail!("Invalid flags");
156 }
157 trailing.pop().unwrap().into()
158 };
159
160 Command::Stats { randomize, memory_usage, only, with_deps, path }
161 }
162 "analysis-bench" => {
163 if matches.contains(["-h", "--help"]) {
164 eprintln!(
165 "\
166ra_cli-analysis-bench
167
168USAGE:
169 ra_cli analysis-bench [FLAGS] [OPTIONS] [PATH]
170
171FLAGS:
172 -h, --help Prints help information
173 -v, --verbose
174
175OPTIONS:
176 --complete <PATH:LINE:COLUMN> Compute completions at this location
177 --highlight <PATH> Hightlight this file
178
179ARGS:
180 <PATH> Project to analyse"
181 );
182 return Ok(Err(HelpPrinted));
183 }
184
185 let path: PathBuf = matches.opt_value_from_str("--path")?.unwrap_or_default();
186 let highlight_path: Option<String> = matches.opt_value_from_str("--highlight")?;
187 let complete_path: Option<Position> = matches.opt_value_from_str("--complete")?;
188 let goto_def_path: Option<Position> = matches.opt_value_from_str("--goto-def")?;
189 let what = match (highlight_path, complete_path, goto_def_path) {
190 (Some(path), None, None) => BenchWhat::Highlight { path: path.into() },
191 (None, Some(position), None) => BenchWhat::Complete(position),
192 (None, None, Some(position)) => BenchWhat::GotoDef(position),
193 _ => panic!(
194 "exactly one of `--highlight`, `--complete` or `--goto-def` must be set"
195 ),
196 };
197 Command::Bench { path, what }
198 }
199 _ => {
200 eprintln!(
201 "\
202ra-cli
203
204USAGE:
205 ra_cli <SUBCOMMAND>
206
207FLAGS:
208 -h, --help Prints help information
209
210SUBCOMMANDS:
211 analysis-bench
212 analysis-stats
213 highlight
214 parse
215 symbols"
216 );
217 return Ok(Err(HelpPrinted));
218 }
219 };
220 Ok(Ok(Args { verbosity, command }))
221 }
222}
223
224pub(crate) struct HelpPrinted;
225
226fn handle_extra_flags(e: pico_args::Error) -> Result<()> {
227 if let pico_args::Error::UnusedArgsLeft(flags) = e {
228 let mut invalid_flags = String::new();
229 for flag in flags {
230 write!(&mut invalid_flags, "{}, ", flag)?;
231 }
232 let (invalid_flags, _) = invalid_flags.split_at(invalid_flags.len() - 2);
233 bail!("Invalid flags: {}", invalid_flags);
234 } else {
235 bail!(e);
236 }
237}