docs(lex): Provide examples

This commit is contained in:
Ed Page 2022-04-15 11:36:12 -05:00
parent 96dc6daa9e
commit c3445e05b5

View File

@ -1,3 +1,111 @@
//! Minimal, flexible command-line parser
//!
//! As opposed to a declarative parser, this processes arguments as a stream. The caller
//! decides when to treat an argument as a flag or value.
//!
//! # Examples
//!
//! ```rust
//! # use std::path::PathBuf;
//! # type BoxedError = Box<dyn std::error::Error + Send + Sync>;
//! #[derive(Debug)]
//! struct Args {
//! paths: Vec<PathBuf>,
//! color: Color,
//! verbosity: usize,
//! }
//!
//! #[derive(Debug)]
//! enum Color {
//! Always,
//! Auto,
//! Never,
//! }
//!
//! impl Color {
//! fn parse(s: Option<&clap_lex::RawOsStr>) -> Result<Self, BoxedError> {
//! let s = s.map(|s| s.to_str().ok_or(s));
//! match s {
//! Some(Ok("always")) | Some(Ok("")) | None => {
//! Ok(Color::Always)
//! }
//! Some(Ok("auto")) => {
//! Ok(Color::Auto)
//! }
//! Some(Ok("never")) => {
//! Ok(Color::Never)
//! }
//! Some(invalid) => {
//! Err(format!("Invalid value for `--color`, {:?}", invalid).into())
//! }
//! }
//! }
//! }
//!
//! fn parse_args(
//! raw: impl IntoIterator<Item=impl Into<std::ffi::OsString>>
//! ) -> Result<Args, BoxedError> {
//! let mut args = Args {
//! paths: Vec::new(),
//! color: Color::Auto,
//! verbosity: 0,
//! };
//!
//! let raw = clap_lex::RawArgs::from_iter(raw);
//! let mut cursor = raw.cursor();
//! raw.next(&mut cursor); // Skip the bin
//! while let Some(arg) = raw.next(&mut cursor) {
//! if arg.is_escape() {
//! args.paths.extend(raw.remaining(&mut cursor).map(PathBuf::from));
//! } else if arg.is_stdio() {
//! args.paths.push(PathBuf::from("-"));
//! } else if let Some((long, value)) = arg.to_long() {
//! match long {
//! Ok("verbose") => {
//! if let Some(value) = value {
//! return Err(format!("`--verbose` does not take a value, got `{:?}`", value).into());
//! }
//! args.verbosity += 1;
//! }
//! Ok("color") => {
//! args.color = Color::parse(value)?;
//! }
//! _ => {
//! return Err(
//! format!("Unexpected flag: --{}", arg.display()).into()
//! );
//! }
//! }
//! } else if let Some(mut shorts) = arg.to_short() {
//! while let Some(short) = shorts.next_flag() {
//! match short {
//! Ok('v') => {
//! args.verbosity += 1;
//! }
//! Ok('c') => {
//! let value = shorts.next_value_os();
//! args.color = Color::parse(value)?;
//! }
//! Ok(c) => {
//! return Err(format!("Unexpected flag: -{}", c).into());
//! }
//! Err(e) => {
//! return Err(format!("Unexpected flag: -{}", e.to_str_lossy()).into());
//! }
//! }
//! }
//! } else {
//! args.paths.push(PathBuf::from(arg.to_value_os().to_os_str().into_owned()));
//! }
//! }
//!
//! Ok(args)
//! }
//!
//! let args = parse_args(["bin", "--hello", "world"]);
//! println!("{:?}", args);
//! ```
use std::ffi::OsStr;
use std::ffi::OsString;
@ -13,7 +121,54 @@ pub struct RawArgs {
}
impl RawArgs {
//// Create an argument list to parse
///
/// # Example
///
/// ```rust,no_run
/// # use std::path::PathBuf;
/// let raw = clap_lex::RawArgs::from_args();
/// let mut cursor = raw.cursor();
/// let _bin = raw.next_os(&mut cursor);
///
/// let mut paths = raw.remaining(&mut cursor).map(PathBuf::from).collect::<Vec<_>>();
/// println!("{:?}", paths);
/// ```
pub fn from_args() -> Self {
Self::from_iter(std::env::args_os())
}
//// Create an argument list to parse
///
/// # Example
///
/// ```rust,no_run
/// # use std::path::PathBuf;
/// let raw = clap_lex::RawArgs::from_iter(["bin", "foo.txt"]);
/// let mut cursor = raw.cursor();
/// let _bin = raw.next_os(&mut cursor);
///
/// let mut paths = raw.remaining(&mut cursor).map(PathBuf::from).collect::<Vec<_>>();
/// println!("{:?}", paths);
/// ```
pub fn from_iter(iter: impl IntoIterator<Item = impl Into<std::ffi::OsString>>) -> Self {
let iter = iter.into_iter();
Self::from(iter)
}
/// Create a cursor for walking the arguments
///
/// # Example
///
/// ```rust,no_run
/// # use std::path::PathBuf;
/// let raw = clap_lex::RawArgs::from_iter(["bin", "foo.txt"]);
/// let mut cursor = raw.cursor();
/// let _bin = raw.next_os(&mut cursor);
///
/// let mut paths = raw.remaining(&mut cursor).map(PathBuf::from).collect::<Vec<_>>();
/// println!("{:?}", paths);
/// ```
pub fn cursor(&self) -> ArgCursor {
ArgCursor::new()
}
@ -41,6 +196,18 @@ impl RawArgs {
}
/// Return all remaining raw arguments, advancing the cursor to the end
///
/// # Example
///
/// ```rust,no_run
/// # use std::path::PathBuf;
/// let raw = clap_lex::RawArgs::from_iter(["bin", "foo.txt"]);
/// let mut cursor = raw.cursor();
/// let _bin = raw.next_os(&mut cursor);
///
/// let mut paths = raw.remaining(&mut cursor).map(PathBuf::from).collect::<Vec<_>>();
/// println!("{:?}", paths);
/// ```
pub fn remaining(&self, cursor: &mut ArgCursor) -> impl Iterator<Item = &OsStr> {
let remaining = self.items[cursor.cursor..].iter().map(|s| s.as_os_str());
cursor.cursor = self.items.len();