summaryrefslogtreecommitdiffstats
path: root/vendor/xflags/src
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/src
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/src')
-rw-r--r--vendor/xflags/src/lib.rs289
-rw-r--r--vendor/xflags/src/rt.rs114
2 files changed, 403 insertions, 0 deletions
diff --git a/vendor/xflags/src/lib.rs b/vendor/xflags/src/lib.rs
new file mode 100644
index 000000000..ae347f511
--- /dev/null
+++ b/vendor/xflags/src/lib.rs
@@ -0,0 +1,289 @@
+//! This crates provides a procedural macro for parsing command line arguments.
+//!
+//! It is intended for use in development tools, so it emphasizes fast compile
+//! times and convenience at the expense of features.
+//!
+//! If you need something more fancy, consider using
+//! [`clap`](https://docs.rs/clap/2.33.3/clap/) instead.
+//!
+//! ## Example
+//!
+//! ```
+//! mod flags {
+//! use std::path::PathBuf;
+//!
+//! xflags::xflags! {
+//! src "./examples/basic.rs"
+//!
+//! cmd my-command
+//! required path: PathBuf
+//! {
+//! optional -v, --verbose
+//! }
+//! }
+//!
+//! // generated start
+//! // The following code is generated by `xflags` macro.
+//! // Run `env UPDATE_XFLAGS=1 cargo build` to regenerate.
+//! #[derive(Debug)]
+//! pub struct MyCommand {
+//! pub path: PathBuf,
+//!
+//! pub verbose: bool,
+//! }
+//!
+//! impl MyCommand {
+//! pub const HELP: &'static str = Self::HELP_;
+//!
+//! pub fn from_env() -> xflags::Result<Self> {
+//! Self::from_env_()
+//! }
+//!
+//! pub fn from_vec(args: Vec<std::ffi::OsString>) -> xflags::Result<Self> {
+//! Self::from_vec_(args)
+//! }
+//! }
+//! // generated end
+//! }
+//!
+//! fn main() {
+//! let flags = flags::MyCommand::from_env();
+//! println!("{:#?}", flags);
+//! }
+//! ```
+//!
+//! To make the macro less opaque, `xflag` can generate `struct` describing the
+//! CLI in-place. To disable this behavior, omit the `src` attribute.
+//!
+//! xflags correctly handles non-utf8 arguments.
+//!
+//! ## Syntax Reference
+//!
+//! The **cmd** keyword introduces a command that accepts positional arguments
+//! and switches.
+//!
+//! ```
+//! xflags::xflags! {
+//! cmd command-name { }
+//! }
+//! ```
+//!
+//! Switches are specified inside the curly braces. Long names (`--switch`) are
+//! mandatory, short names (`-s`) are optional. Each switch can be **optional**,
+//! **required**, or **repeated**. Dashes are allowed in switch names.
+//!
+//! ```
+//! xflags::xflags! {
+//! cmd switches {
+//! optional -h, --help
+//! repeated --verbose
+//! required --pass-me
+//! }
+//! }
+//! ```
+//!
+//! Switches can also take values. If the value type is `OsString` or `PathBuf`,
+//! it is created directly from the underlying argument. Otherwise, `FromStr` is
+//! used for parsing
+//!
+//! ```
+//! use std::{path::PathBuf, ffi::OsString};
+//!
+//! xflags::xflags! {
+//! cmd switches-with-values {
+//! optional --config path: PathBuf
+//! repeated --data val: OsString
+//! optional -j, --jobs n: u32
+//! }
+//! }
+//! ```
+//!
+//! Positional arguments are specified before the opening curly brace:
+//!
+//! ```
+//! use std::{path::PathBuf, ffi::OsString};
+//!
+//! xflags::xflags! {
+//! cmd positional-arguments
+//! required program: PathBuf
+//! repeated args: OsString
+//! { }
+//! }
+//! ```
+//!
+//! Nesting **cmd** is allowed:
+//!
+//! ```ignore
+//! xflags::xflags! {
+//! src "./examples/subcommands.rs"
+//! cmd app {
+//! repeated -v, --verbose
+//! cmd foo { optional -s, --switch }
+//! cmd bar {}
+//! }
+//! }
+//!
+//! // generated start
+//! // The following code is generated by `xflags` macro.
+//! // Run `env UPDATE_XFLAGS=1 cargo build` to regenerate.
+//! #[derive(Debug)]
+//! pub struct App {
+//! pub verbose: u32,
+//! pub subcommand: AppCmd,
+//! }
+//!
+//! #[derive(Debug)]
+//! pub enum AppCmd {
+//! Foo(Foo),
+//! Bar(Bar),
+//! }
+//!
+//! #[derive(Debug)]
+//! pub struct Foo {
+//! pub switch: bool,
+//! }
+//!
+//! #[derive(Debug)]
+//! pub struct Bar {
+//! }
+//!
+//! impl App {
+//! pub const HELP: &'static str = Self::HELP_;
+//!
+//! pub fn from_env() -> xflags::Result<Self> {
+//! Self::from_env_()
+//! }
+//!
+//! pub fn from_vec(args: Vec<std::ffi::OsString>) -> xflags::Result<Self> {
+//! Self::from_vec_(args)
+//! }
+//! }
+//! // generated end
+//! ```
+//!
+//! To make subcommand name optional use the **default** keyword to mark a
+//! subcommand to select if no subcommand name is passed. The name of the
+//! default subcommand affects only the name of the generated Rust struct, it
+//! can't be specified explicitly on the command line.
+//!
+//! ```
+//! xflags::xflags! {
+//! cmd app {
+//! repeated -v, --verbose
+//! default cmd foo { optional -s, --switch }
+//! cmd bar {}
+//! }
+//! }
+//! ```
+//!
+//! Commands, arguments, and switches can documented. Doc comments become a part
+//! of generated help:
+//!
+//! ```
+//! mod flags {
+//! use std::path::PathBuf;
+//!
+//! xflags::xflags! {
+//! /// Run basic system diagnostics.
+//! cmd healthck
+//! /// Optional configuration file.
+//! optional config: PathBuf
+//! {
+//! /// Verbosity level, can be repeated multiple times.
+//! repeated -v, --verbose
+//! /// Print the help message.
+//! optional -h, --help
+//! }
+//! }
+//! }
+//!
+//! fn main() {
+//! match flags::Healthck::from_env() {
+//! Ok(flags) => {
+//! if flags.help {
+//! println!("{}", flags::Healthck::HELP);
+//! return;
+//! }
+//! run_checks(flags.config, flags.verbose);
+//! }
+//! Err(err) => {
+//! eprintln!("{}", err);
+//! }
+//! }
+//! }
+//!
+//! # fn run_checks(_config: Option<std::path::PathBuf>, _verbosity: u32) {}
+//! ```
+//!
+//! The **src** keyword controlls how the code generation works. If it is
+//! absent, `xflags` acts as a typical procedure macro, which generates a bunch
+//! of structs and impls.
+//!
+//! If the **src** keyword is present, it should specify the path to the file
+//! with `xflags!` invocation. The path should be relative to the directory with
+//! Cargo.toml. The macro then will avoid generating the structs. Instead, if
+//! the `UPDATE_XFLAGS` environmental variable is set, the macro will write them
+//! directly to the specified file.
+//!
+//! By convention, `xflag!` macro should be invoked from the `flags` submodule.
+//! The `flags::` preffix should be used to refer to command names. Additional
+//! validation logic can go to the `flags` module:
+//!
+//! ```
+//! mod flags {
+//! xflags::xflags! {
+//! cmd my-command {
+//! repeated -v, --verbose
+//! optional -q, --quiet
+//! }
+//! }
+//!
+//! impl MyCommand {
+//! fn validate(&self) -> xflags::Result<()> {
+//! if self.quiet && self.verbose > 0 {
+//! return Err(xflags::Error::new(
+//! "`-q` and `-v` can't be specified at the same time"
+//! ));
+//! }
+//! Ok(())
+//! }
+//! }
+//! }
+//! ```
+
+use std::fmt;
+
+/// Generates a parser for command line arguments from a DSL.
+///
+/// See the module-level for detailed syntax specification.
+pub use xflags_macros::xflags;
+
+pub type Result<T, E = Error> = std::result::Result<T, E>;
+
+/// This type represents an error that can occur during command line argument
+/// parsing.
+#[derive(Debug)]
+pub struct Error {
+ msg: String,
+}
+
+impl fmt::Display for Error {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt::Display::fmt(&self.msg, f)
+ }
+}
+
+impl std::error::Error for Error {}
+
+impl Error {
+ /// Creates a new `Error` from a given message.
+ ///
+ /// Use this to report custom validation errors.
+ pub fn new(message: impl Into<String>) -> Error {
+ Error { msg: message.into() }
+ }
+}
+
+/// Private impl details for macros.
+#[doc(hidden)]
+pub mod rt;
diff --git a/vendor/xflags/src/rt.rs b/vendor/xflags/src/rt.rs
new file mode 100644
index 000000000..3c33196af
--- /dev/null
+++ b/vendor/xflags/src/rt.rs
@@ -0,0 +1,114 @@
+use std::{ffi::OsString, fmt, str::FromStr};
+
+use crate::{Error, Result};
+
+macro_rules! format_err {
+ ($($tt:tt)*) => {
+ Error { msg: format!($($tt)*) }
+ };
+}
+
+macro_rules! bail {
+ ($($tt:tt)*) => {
+ return Err(format_err!($($tt)*))
+ };
+}
+
+pub struct Parser {
+ rargs: Vec<OsString>,
+}
+
+impl Parser {
+ pub fn new(mut args: Vec<OsString>) -> Self {
+ args.reverse();
+ Self { rargs: args }
+ }
+
+ pub fn new_from_env() -> Self {
+ let mut args = std::env::args_os().collect::<Vec<_>>();
+ args.reverse();
+ args.pop();
+ Self { rargs: args }
+ }
+
+ pub fn is_empty(&self) -> bool {
+ self.rargs.is_empty()
+ }
+
+ pub fn peek_flag(&self) -> Option<&str> {
+ self.rargs.last().and_then(|it| it.to_str()).filter(|it| it.starts_with('-'))
+ }
+ pub fn pop_flag(&mut self) -> Option<Result<String, OsString>> {
+ if self.peek_flag().is_some() {
+ self.next().map(|it| it.into_string())
+ } else {
+ self.next().map(Err)
+ }
+ }
+ pub fn push_back(&mut self, arg: Result<String, OsString>) {
+ let arg = match arg {
+ Ok(it) => it.into(),
+ Err(it) => it,
+ };
+ self.rargs.push(arg)
+ }
+
+ pub fn next(&mut self) -> Option<OsString> {
+ self.rargs.pop()
+ }
+
+ pub fn next_value(&mut self, flag: &str) -> Result<OsString> {
+ if self.peek_flag().is_some() {
+ bail!("expected a value for `{}`", flag)
+ }
+ self.next().ok_or_else(|| format_err!("expected a value for `{}`", flag))
+ }
+
+ pub fn next_value_from_str<T: FromStr>(&mut self, flag: &str) -> Result<T>
+ where
+ T::Err: fmt::Display,
+ {
+ let value = self.next_value(flag)?;
+ self.value_from_str(flag, value)
+ }
+
+ pub fn value_from_str<T: FromStr>(&mut self, flag: &str, value: OsString) -> Result<T>
+ where
+ T::Err: fmt::Display,
+ {
+ match value.into_string() {
+ Ok(str) => {
+ str.parse::<T>().map_err(|err| format_err!("can't parse `{}`, {}", flag, err))
+ }
+ Err(it) => {
+ bail!("can't parse `{}`, invalid utf8: {:?}", flag, it)
+ }
+ }
+ }
+
+ pub fn unexpected_flag(&self, flag: &str) -> Error {
+ format_err!("unexpected flag: `{}`", flag)
+ }
+
+ pub fn unexpected_arg(&self, arg: OsString) -> Error {
+ format_err!("unexpected argument: {:?}", arg)
+ }
+
+ pub fn optional<T>(&self, flag: &str, mut vals: Vec<T>) -> Result<Option<T>> {
+ if vals.len() > 1 {
+ bail!("flag specified more than once: `{}`", flag)
+ }
+ Ok(vals.pop())
+ }
+
+ pub fn required<T>(&self, flag: &str, mut vals: Vec<T>) -> Result<T> {
+ if vals.len() > 1 {
+ bail!("flag specified more than once: `{}`", flag)
+ }
+ vals.pop().ok_or_else(|| format_err!("flag is required: `{}`", flag))
+ }
+
+ pub fn subcommand<T>(&self, cmd: Option<T>) -> Result<T> {
+ cmd.ok_or_else(|| format_err!("subcommand is required"))
+ }
+}