summaryrefslogtreecommitdiffstats
path: root/vendor/xflags-macros/tests
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
commit698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch)
tree173a775858bd501c378080a10dca74132f05bc50 /vendor/xflags-macros/tests
parentInitial commit. (diff)
downloadrustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz
rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/xflags-macros/tests')
-rw-r--r--vendor/xflags-macros/tests/it/help.rs144
-rw-r--r--vendor/xflags-macros/tests/it/main.rs198
-rw-r--r--vendor/xflags-macros/tests/it/repeated_pos.rs94
-rw-r--r--vendor/xflags-macros/tests/it/smoke.rs112
-rw-r--r--vendor/xflags-macros/tests/it/src/help.rs25
-rw-r--r--vendor/xflags-macros/tests/it/src/repeated_pos.rs9
-rw-r--r--vendor/xflags-macros/tests/it/src/smoke.rs15
-rw-r--r--vendor/xflags-macros/tests/it/src/subcommands.rs20
-rw-r--r--vendor/xflags-macros/tests/it/subcommands.rs225
9 files changed, 842 insertions, 0 deletions
diff --git a/vendor/xflags-macros/tests/it/help.rs b/vendor/xflags-macros/tests/it/help.rs
new file mode 100644
index 000000000..36a966485
--- /dev/null
+++ b/vendor/xflags-macros/tests/it/help.rs
@@ -0,0 +1,144 @@
+#![allow(unused)]
+use std::{ffi::OsString, path::PathBuf};
+
+#[derive(Debug)]
+pub struct Helpful {
+ pub src: Option<PathBuf>,
+ pub extra: Option<String>,
+
+ pub switch: (),
+ pub subcommand: HelpfulCmd,
+}
+
+#[derive(Debug)]
+pub enum HelpfulCmd {
+ Sub(Sub),
+}
+
+#[derive(Debug)]
+pub struct Sub {
+ pub flag: bool,
+}
+
+impl Helpful {
+ pub const HELP: &'static str = Self::HELP_;
+
+ #[allow(dead_code)]
+ pub fn from_env() -> xflags::Result<Self> {
+ Self::from_env_()
+ }
+
+ #[allow(dead_code)]
+ pub fn from_vec(args: Vec<std::ffi::OsString>) -> xflags::Result<Self> {
+ Self::from_vec_(args)
+ }
+}
+
+impl Helpful {
+ fn from_env_() -> xflags::Result<Self> {
+ let mut p = xflags::rt::Parser::new_from_env();
+ Self::parse_(&mut p)
+ }
+ fn from_vec_(args: Vec<std::ffi::OsString>) -> xflags::Result<Self> {
+ let mut p = xflags::rt::Parser::new(args);
+ Self::parse_(&mut p)
+ }
+}
+
+impl Helpful {
+ fn parse_(p_: &mut xflags::rt::Parser) -> xflags::Result<Self> {
+ let mut switch = Vec::new();
+
+ let mut src = (false, Vec::new());
+ let mut extra = (false, Vec::new());
+
+ let mut sub_ = None;
+ while let Some(arg_) = p_.pop_flag() {
+ match arg_ {
+ Ok(flag_) => match flag_.as_str() {
+ "--switch" | "-s" => switch.push(()),
+ _ => return Err(p_.unexpected_flag(&flag_)),
+ },
+ Err(arg_) => {
+ match arg_.to_str().unwrap_or("") {
+ "sub" => {
+ sub_ = Some(HelpfulCmd::Sub(Sub::parse_(p_)?));
+ break;
+ }
+ _ => (),
+ }
+ if let (done_ @ false, buf_) = &mut src {
+ buf_.push(arg_.into());
+ *done_ = true;
+ continue;
+ }
+ if let (done_ @ false, buf_) = &mut extra {
+ buf_.push(p_.value_from_str::<String>("extra", arg_)?);
+ *done_ = true;
+ continue;
+ }
+ return Err(p_.unexpected_arg(arg_));
+ }
+ }
+ }
+ Ok(Self {
+ src: p_.optional("src", src.1)?,
+ extra: p_.optional("extra", extra.1)?,
+
+ switch: p_.required("--switch", switch)?,
+ subcommand: p_.subcommand(sub_)?,
+ })
+ }
+}
+
+impl Sub {
+ fn parse_(p_: &mut xflags::rt::Parser) -> xflags::Result<Self> {
+ let mut flag = Vec::new();
+
+ while let Some(arg_) = p_.pop_flag() {
+ match arg_ {
+ Ok(flag_) => match flag_.as_str() {
+ "--flag" | "-f" => flag.push(()),
+ _ => return Err(p_.unexpected_flag(&flag_)),
+ },
+ Err(arg_) => {
+ return Err(p_.unexpected_arg(arg_));
+ }
+ }
+ }
+ Ok(Self { flag: p_.optional("--flag", flag)?.is_some() })
+ }
+}
+impl Helpful {
+ const HELP_: &'static str = "\
+helpful
+ Does stuff
+
+ Helpful stuff.
+
+ARGS:
+ [src]
+ With an arg.
+
+ [extra]
+ Another arg.
+
+ This time, we provide some extra info about the
+ arg. Maybe some caveats, or what kinds of
+ values are accepted.
+
+OPTIONS:
+ -s, --switch
+ And a switch.
+
+SUBCOMMANDS:
+
+helpful sub
+ And even a subcommand!
+
+ OPTIONS:
+ -f, --flag
+ With an optional flag. This has a really long
+ description which spans multiple lines.
+";
+}
diff --git a/vendor/xflags-macros/tests/it/main.rs b/vendor/xflags-macros/tests/it/main.rs
new file mode 100644
index 000000000..1ce058814
--- /dev/null
+++ b/vendor/xflags-macros/tests/it/main.rs
@@ -0,0 +1,198 @@
+mod repeated_pos;
+mod smoke;
+mod subcommands;
+mod help;
+
+use std::{ffi::OsString, fmt};
+
+use expect_test::{expect, Expect};
+
+fn check<F, A>(f: F, args: &str, expect: Expect)
+where
+ F: FnOnce(Vec<OsString>) -> xflags::Result<A>,
+ A: fmt::Debug,
+{
+ let args = args.split_ascii_whitespace().map(OsString::from).collect::<Vec<_>>();
+ let res = f(args);
+ match res {
+ Ok(args) => {
+ expect.assert_debug_eq(&args);
+ }
+ Err(err) => {
+ expect.assert_eq(&err.to_string());
+ }
+ }
+}
+
+#[test]
+fn smoke() {
+ check(
+ smoke::RustAnalyzer::from_vec,
+ "-n 92 .",
+ expect![[r#"
+ RustAnalyzer {
+ workspace: ".",
+ jobs: None,
+ log_file: None,
+ verbose: 0,
+ number: 92,
+ data: [],
+ emoji: false,
+ }
+ "#]],
+ );
+ check(
+ smoke::RustAnalyzer::from_vec,
+ "-n 92 -v --verbose -v --data 0xDEAD --log-file /tmp/log.txt --data 0xBEEF .",
+ expect![[r#"
+ RustAnalyzer {
+ workspace: ".",
+ jobs: None,
+ log_file: Some(
+ "/tmp/log.txt",
+ ),
+ verbose: 3,
+ number: 92,
+ data: [
+ "0xDEAD",
+ "0xBEEF",
+ ],
+ emoji: false,
+ }
+ "#]],
+ );
+
+ check(
+ smoke::RustAnalyzer::from_vec,
+ "-n 92 --werbose",
+ expect![[r#"unexpected flag: `--werbose`"#]],
+ );
+ check(smoke::RustAnalyzer::from_vec, "", expect![[r#"flag is required: `workspace`"#]]);
+ check(smoke::RustAnalyzer::from_vec, ".", expect![[r#"flag is required: `--number`"#]]);
+ check(smoke::RustAnalyzer::from_vec, "-n", expect![[r#"expected a value for `-n`"#]]);
+ check(
+ smoke::RustAnalyzer::from_vec,
+ "-n lol",
+ expect![[r#"can't parse `-n`, invalid digit found in string"#]],
+ );
+ check(
+ smoke::RustAnalyzer::from_vec,
+ "-n 1 -n 2 .",
+ expect![[r#"flag specified more than once: `--number`"#]],
+ );
+ check(
+ smoke::RustAnalyzer::from_vec,
+ "-n 1 . 92 lol",
+ expect![[r#"unexpected argument: "lol""#]],
+ );
+ check(
+ smoke::RustAnalyzer::from_vec,
+ "-n 1 . --emoji --emoji",
+ expect![[r#"flag specified more than once: `--emoji`"#]],
+ );
+}
+
+#[test]
+fn repeated_argument() {
+ check(
+ repeated_pos::RepeatedPos::from_vec,
+ "a 11 c d e f",
+ expect![[r#"
+ RepeatedPos {
+ a: "a",
+ b: Some(
+ 11,
+ ),
+ c: Some(
+ "c",
+ ),
+ rest: [
+ "d",
+ "e",
+ "f",
+ ],
+ }
+ "#]],
+ );
+}
+
+#[test]
+fn subcommands() {
+ check(
+ subcommands::RustAnalyzer::from_vec,
+ "server",
+ expect![[r#"
+ RustAnalyzer {
+ verbose: 0,
+ subcommand: Server(
+ Server {
+ dir: None,
+ subcommand: Launch(
+ Launch {
+ log: false,
+ },
+ ),
+ },
+ ),
+ }
+ "#]],
+ );
+
+ check(
+ subcommands::RustAnalyzer::from_vec,
+ "server --dir . --log",
+ expect![[r#"
+ RustAnalyzer {
+ verbose: 0,
+ subcommand: Server(
+ Server {
+ dir: Some(
+ ".",
+ ),
+ subcommand: Launch(
+ Launch {
+ log: true,
+ },
+ ),
+ },
+ ),
+ }
+ "#]],
+ );
+
+ check(
+ subcommands::RustAnalyzer::from_vec,
+ "server watch",
+ expect![[r#"
+ RustAnalyzer {
+ verbose: 0,
+ subcommand: Server(
+ Server {
+ dir: None,
+ subcommand: Watch(
+ Watch,
+ ),
+ },
+ ),
+ }
+ "#]],
+ );
+
+ check(
+ subcommands::RustAnalyzer::from_vec,
+ "-v analysis-stats . --parallel",
+ expect![[r#"
+ RustAnalyzer {
+ verbose: 1,
+ subcommand: AnalysisStats(
+ AnalysisStats {
+ path: ".",
+ parallel: true,
+ },
+ ),
+ }
+ "#]],
+ );
+
+ check(subcommands::RustAnalyzer::from_vec, "", expect![[r#"subcommand is required"#]]);
+}
diff --git a/vendor/xflags-macros/tests/it/repeated_pos.rs b/vendor/xflags-macros/tests/it/repeated_pos.rs
new file mode 100644
index 000000000..334af371d
--- /dev/null
+++ b/vendor/xflags-macros/tests/it/repeated_pos.rs
@@ -0,0 +1,94 @@
+#![allow(unused)]
+use std::{ffi::OsString, path::PathBuf};
+
+#[derive(Debug)]
+pub struct RepeatedPos {
+ pub a: PathBuf,
+ pub b: Option<u32>,
+ pub c: Option<OsString>,
+ pub rest: Vec<OsString>,
+}
+
+impl RepeatedPos {
+ pub const HELP: &'static str = Self::HELP_;
+
+ #[allow(dead_code)]
+ pub fn from_env() -> xflags::Result<Self> {
+ Self::from_env_()
+ }
+
+ #[allow(dead_code)]
+ pub fn from_vec(args: Vec<std::ffi::OsString>) -> xflags::Result<Self> {
+ Self::from_vec_(args)
+ }
+}
+
+impl RepeatedPos {
+ fn from_env_() -> xflags::Result<Self> {
+ let mut p = xflags::rt::Parser::new_from_env();
+ Self::parse_(&mut p)
+ }
+ fn from_vec_(args: Vec<std::ffi::OsString>) -> xflags::Result<Self> {
+ let mut p = xflags::rt::Parser::new(args);
+ Self::parse_(&mut p)
+ }
+}
+
+impl RepeatedPos {
+ fn parse_(p_: &mut xflags::rt::Parser) -> xflags::Result<Self> {
+ let mut a = (false, Vec::new());
+ let mut b = (false, Vec::new());
+ let mut c = (false, Vec::new());
+ let mut rest = (false, Vec::new());
+
+ while let Some(arg_) = p_.pop_flag() {
+ match arg_ {
+ Ok(flag_) => match flag_.as_str() {
+ _ => return Err(p_.unexpected_flag(&flag_)),
+ },
+ Err(arg_) => {
+ if let (done_ @ false, buf_) = &mut a {
+ buf_.push(arg_.into());
+ *done_ = true;
+ continue;
+ }
+ if let (done_ @ false, buf_) = &mut b {
+ buf_.push(p_.value_from_str::<u32>("b", arg_)?);
+ *done_ = true;
+ continue;
+ }
+ if let (done_ @ false, buf_) = &mut c {
+ buf_.push(arg_.into());
+ *done_ = true;
+ continue;
+ }
+ if let (false, buf_) = &mut rest {
+ buf_.push(arg_.into());
+ continue;
+ }
+ return Err(p_.unexpected_arg(arg_));
+ }
+ }
+ }
+ Ok(Self {
+ a: p_.required("a", a.1)?,
+ b: p_.optional("b", b.1)?,
+ c: p_.optional("c", c.1)?,
+ rest: rest.1,
+ })
+ }
+}
+impl RepeatedPos {
+ const HELP_: &'static str = "\
+RepeatedPos
+
+ARGS:
+ <a>
+
+ [b]
+
+ [c]
+
+ <rest>...
+";
+}
diff --git a/vendor/xflags-macros/tests/it/smoke.rs b/vendor/xflags-macros/tests/it/smoke.rs
new file mode 100644
index 000000000..e22c4f1f6
--- /dev/null
+++ b/vendor/xflags-macros/tests/it/smoke.rs
@@ -0,0 +1,112 @@
+#![allow(unused)]
+use std::{ffi::OsString, path::PathBuf};
+
+#[derive(Debug)]
+pub struct RustAnalyzer {
+ pub workspace: PathBuf,
+ pub jobs: Option<u32>,
+
+ pub log_file: Option<PathBuf>,
+ pub verbose: u32,
+ pub number: u32,
+ pub data: Vec<OsString>,
+ pub emoji: bool,
+}
+
+impl RustAnalyzer {
+ pub const HELP: &'static str = Self::HELP_;
+
+ #[allow(dead_code)]
+ pub fn from_env() -> xflags::Result<Self> {
+ Self::from_env_()
+ }
+
+ #[allow(dead_code)]
+ pub fn from_vec(args: Vec<std::ffi::OsString>) -> xflags::Result<Self> {
+ Self::from_vec_(args)
+ }
+}
+
+impl RustAnalyzer {
+ fn from_env_() -> xflags::Result<Self> {
+ let mut p = xflags::rt::Parser::new_from_env();
+ Self::parse_(&mut p)
+ }
+ fn from_vec_(args: Vec<std::ffi::OsString>) -> xflags::Result<Self> {
+ let mut p = xflags::rt::Parser::new(args);
+ Self::parse_(&mut p)
+ }
+}
+
+impl RustAnalyzer {
+ fn parse_(p_: &mut xflags::rt::Parser) -> xflags::Result<Self> {
+ let mut log_file = Vec::new();
+ let mut verbose = Vec::new();
+ let mut number = Vec::new();
+ let mut data = Vec::new();
+ let mut emoji = Vec::new();
+
+ let mut workspace = (false, Vec::new());
+ let mut jobs = (false, Vec::new());
+
+ while let Some(arg_) = p_.pop_flag() {
+ match arg_ {
+ Ok(flag_) => match flag_.as_str() {
+ "--log-file" => log_file.push(p_.next_value(&flag_)?.into()),
+ "--verbose" | "-v" => verbose.push(()),
+ "--number" | "-n" => number.push(p_.next_value_from_str::<u32>(&flag_)?),
+ "--data" => data.push(p_.next_value(&flag_)?.into()),
+ "--emoji" => emoji.push(()),
+ _ => return Err(p_.unexpected_flag(&flag_)),
+ },
+ Err(arg_) => {
+ if let (done_ @ false, buf_) = &mut workspace {
+ buf_.push(arg_.into());
+ *done_ = true;
+ continue;
+ }
+ if let (done_ @ false, buf_) = &mut jobs {
+ buf_.push(p_.value_from_str::<u32>("jobs", arg_)?);
+ *done_ = true;
+ continue;
+ }
+ return Err(p_.unexpected_arg(arg_));
+ }
+ }
+ }
+ Ok(Self {
+ workspace: p_.required("workspace", workspace.1)?,
+ jobs: p_.optional("jobs", jobs.1)?,
+
+ log_file: p_.optional("--log-file", log_file)?,
+ verbose: verbose.len() as u32,
+ number: p_.required("--number", number)?,
+ data: data,
+ emoji: p_.optional("--emoji", emoji)?.is_some(),
+ })
+ }
+}
+impl RustAnalyzer {
+ const HELP_: &'static str = "\
+rust-analyzer
+ LSP server for rust.
+
+ARGS:
+ <workspace>
+
+ [jobs]
+ Number of concurrent jobs.
+
+OPTIONS:
+ --log-file <path>
+ Path to log file. By default, logs go to stderr.
+
+ -v, --verbose
+
+ -n, --number <n>
+
+ --data <value>
+
+ --emoji
+";
+}
diff --git a/vendor/xflags-macros/tests/it/src/help.rs b/vendor/xflags-macros/tests/it/src/help.rs
new file mode 100644
index 000000000..d552c1e63
--- /dev/null
+++ b/vendor/xflags-macros/tests/it/src/help.rs
@@ -0,0 +1,25 @@
+xflags! {
+ /// Does stuff
+ ///
+ /// Helpful stuff.
+ cmd helpful
+ /// With an arg.
+ optional src: PathBuf
+ /// Another arg.
+ ///
+ /// This time, we provide some extra info about the
+ /// arg. Maybe some caveats, or what kinds of
+ /// values are accepted.
+ optional extra: String
+ {
+ /// And a switch.
+ required -s, --switch
+
+ /// And even a subcommand!
+ cmd sub {
+ /// With an optional flag. This has a really long
+ /// description which spans multiple lines.
+ optional -f, --flag
+ }
+ }
+}
diff --git a/vendor/xflags-macros/tests/it/src/repeated_pos.rs b/vendor/xflags-macros/tests/it/src/repeated_pos.rs
new file mode 100644
index 000000000..4106c65eb
--- /dev/null
+++ b/vendor/xflags-macros/tests/it/src/repeated_pos.rs
@@ -0,0 +1,9 @@
+xflags! {
+ cmd RepeatedPos
+ required a: PathBuf
+ optional b: u32
+ optional c: OsString
+ repeated rest: OsString
+ {
+ }
+}
diff --git a/vendor/xflags-macros/tests/it/src/smoke.rs b/vendor/xflags-macros/tests/it/src/smoke.rs
new file mode 100644
index 000000000..ae303779e
--- /dev/null
+++ b/vendor/xflags-macros/tests/it/src/smoke.rs
@@ -0,0 +1,15 @@
+xflags! {
+ /// LSP server for rust.
+ cmd rust-analyzer
+ required workspace: PathBuf
+ /// Number of concurrent jobs.
+ optional jobs: u32
+ {
+ /// Path to log file. By default, logs go to stderr.
+ optional --log-file path: PathBuf
+ repeated -v, --verbose
+ required -n, --number n: u32
+ repeated --data value: OsString
+ optional --emoji
+ }
+}
diff --git a/vendor/xflags-macros/tests/it/src/subcommands.rs b/vendor/xflags-macros/tests/it/src/subcommands.rs
new file mode 100644
index 000000000..70a0a5049
--- /dev/null
+++ b/vendor/xflags-macros/tests/it/src/subcommands.rs
@@ -0,0 +1,20 @@
+xflags! {
+ cmd rust-analyzer {
+ repeated -v, --verbose
+
+ cmd server {
+ optional --dir path:PathBuf
+ default cmd launch {
+ optional --log
+ }
+ cmd watch {
+ }
+ }
+
+ cmd analysis-stats
+ required path: PathBuf
+ {
+ optional --parallel
+ }
+ }
+}
diff --git a/vendor/xflags-macros/tests/it/subcommands.rs b/vendor/xflags-macros/tests/it/subcommands.rs
new file mode 100644
index 000000000..7941a395d
--- /dev/null
+++ b/vendor/xflags-macros/tests/it/subcommands.rs
@@ -0,0 +1,225 @@
+#![allow(unused)]
+use std::{ffi::OsString, path::PathBuf};
+
+#[derive(Debug)]
+pub struct RustAnalyzer {
+ pub verbose: u32,
+ pub subcommand: RustAnalyzerCmd,
+}
+
+#[derive(Debug)]
+pub enum RustAnalyzerCmd {
+ Server(Server),
+ AnalysisStats(AnalysisStats),
+}
+
+#[derive(Debug)]
+pub struct Server {
+ pub dir: Option<PathBuf>,
+ pub subcommand: ServerCmd,
+}
+
+#[derive(Debug)]
+pub enum ServerCmd {
+ Launch(Launch),
+ Watch(Watch),
+}
+
+#[derive(Debug)]
+pub struct Launch {
+ pub log: bool,
+}
+
+#[derive(Debug)]
+pub struct Watch;
+
+#[derive(Debug)]
+pub struct AnalysisStats {
+ pub path: PathBuf,
+
+ pub parallel: bool,
+}
+
+impl RustAnalyzer {
+ pub const HELP: &'static str = Self::HELP_;
+
+ #[allow(dead_code)]
+ pub fn from_env() -> xflags::Result<Self> {
+ Self::from_env_()
+ }
+
+ #[allow(dead_code)]
+ pub fn from_vec(args: Vec<std::ffi::OsString>) -> xflags::Result<Self> {
+ Self::from_vec_(args)
+ }
+}
+
+impl RustAnalyzer {
+ fn from_env_() -> xflags::Result<Self> {
+ let mut p = xflags::rt::Parser::new_from_env();
+ Self::parse_(&mut p)
+ }
+ fn from_vec_(args: Vec<std::ffi::OsString>) -> xflags::Result<Self> {
+ let mut p = xflags::rt::Parser::new(args);
+ Self::parse_(&mut p)
+ }
+}
+
+impl RustAnalyzer {
+ fn parse_(p_: &mut xflags::rt::Parser) -> xflags::Result<Self> {
+ let mut verbose = Vec::new();
+
+ let mut sub_ = None;
+ while let Some(arg_) = p_.pop_flag() {
+ match arg_ {
+ Ok(flag_) => match flag_.as_str() {
+ "--verbose" | "-v" => verbose.push(()),
+ _ => return Err(p_.unexpected_flag(&flag_)),
+ },
+ Err(arg_) => {
+ match arg_.to_str().unwrap_or("") {
+ "server" => {
+ sub_ = Some(RustAnalyzerCmd::Server(Server::parse_(p_)?));
+ break;
+ }
+ "analysis-stats" => {
+ sub_ = Some(RustAnalyzerCmd::AnalysisStats(AnalysisStats::parse_(p_)?));
+ break;
+ }
+ _ => (),
+ }
+ return Err(p_.unexpected_arg(arg_));
+ }
+ }
+ }
+ Ok(Self { verbose: verbose.len() as u32, subcommand: p_.subcommand(sub_)? })
+ }
+}
+
+impl Server {
+ fn parse_(p_: &mut xflags::rt::Parser) -> xflags::Result<Self> {
+ let mut dir = Vec::new();
+
+ let mut sub_ = None;
+ while let Some(arg_) = p_.pop_flag() {
+ match arg_ {
+ Ok(flag_) => match flag_.as_str() {
+ "--dir" => dir.push(p_.next_value(&flag_)?.into()),
+ _ => {
+ p_.push_back(Ok(flag_));
+ break;
+ }
+ },
+ Err(arg_) => {
+ match arg_.to_str().unwrap_or("") {
+ "watch" => {
+ sub_ = Some(ServerCmd::Watch(Watch::parse_(p_)?));
+ break;
+ }
+ _ => (),
+ }
+ p_.push_back(Err(arg_));
+ break;
+ }
+ }
+ }
+ if sub_.is_none() {
+ sub_ = Some(ServerCmd::Launch(Launch::parse_(p_)?));
+ }
+ Ok(Self { dir: p_.optional("--dir", dir)?, subcommand: p_.subcommand(sub_)? })
+ }
+}
+
+impl Launch {
+ fn parse_(p_: &mut xflags::rt::Parser) -> xflags::Result<Self> {
+ let mut log = Vec::new();
+
+ while let Some(arg_) = p_.pop_flag() {
+ match arg_ {
+ Ok(flag_) => match flag_.as_str() {
+ "--log" => log.push(()),
+ _ => return Err(p_.unexpected_flag(&flag_)),
+ },
+ Err(arg_) => {
+ return Err(p_.unexpected_arg(arg_));
+ }
+ }
+ }
+ Ok(Self { log: p_.optional("--log", log)?.is_some() })
+ }
+}
+
+impl Watch {
+ fn parse_(p_: &mut xflags::rt::Parser) -> xflags::Result<Self> {
+ while let Some(arg_) = p_.pop_flag() {
+ match arg_ {
+ Ok(flag_) => match flag_.as_str() {
+ _ => return Err(p_.unexpected_flag(&flag_)),
+ },
+ Err(arg_) => {
+ return Err(p_.unexpected_arg(arg_));
+ }
+ }
+ }
+ Ok(Self {})
+ }
+}
+
+impl AnalysisStats {
+ fn parse_(p_: &mut xflags::rt::Parser) -> xflags::Result<Self> {
+ let mut parallel = Vec::new();
+
+ let mut path = (false, Vec::new());
+
+ while let Some(arg_) = p_.pop_flag() {
+ match arg_ {
+ Ok(flag_) => match flag_.as_str() {
+ "--parallel" => parallel.push(()),
+ _ => return Err(p_.unexpected_flag(&flag_)),
+ },
+ Err(arg_) => {
+ if let (done_ @ false, buf_) = &mut path {
+ buf_.push(arg_.into());
+ *done_ = true;
+ continue;
+ }
+ return Err(p_.unexpected_arg(arg_));
+ }
+ }
+ }
+ Ok(Self {
+ path: p_.required("path", path.1)?,
+
+ parallel: p_.optional("--parallel", parallel)?.is_some(),
+ })
+ }
+}
+impl RustAnalyzer {
+ const HELP_: &'static str = "\
+rust-analyzer
+
+OPTIONS:
+ -v, --verbose
+
+SUBCOMMANDS:
+
+rust-analyzer server
+
+ OPTIONS:
+ --dir <path>
+
+ --log
+
+
+rust-analyzer server watch
+
+
+rust-analyzer analysis-stats
+
+ ARGS:
+ <path>
+
+ OPTIONS:
+ --parallel
+";
+}