Parser

Struct Parser 

Source
pub struct Parser<I: Iterator> { /* private fields */ }
Expand description

A stateful command-line argument parser.

The Parser processes arguments one at a time using an iterator-based approach, maintaining internal state to handle complex scenarios like combined short options and option values.

§Type Parameters

  • I - An iterator that yields items convertible to String (e.g., &str, String, OsString)

§Examples

use sap::{Parser, Argument};

// Parse from environment arguments
let mut parser = Parser::from_env().unwrap();

// Or parse from string arrays directly
let mut parser = Parser::from_arbitrary(["myprogram", "-abc", "--verbose"]).unwrap();

// Process arguments one by one
while let Some(arg) = parser.forward().unwrap() {
    match arg {
        Argument::Short(c) => println!("Short option: -{}", c),
        Argument::Long(name) => println!("Long option: --{}", name),
        Argument::Value(val) => println!("Value: {}", val),
        Argument::Stdio => println!("Stdin/stdout argument"),
    }
}

Implementations§

Source§

impl Parser<Args>

Source

pub fn from_env() -> Result<Self>

Creates a Parser using the program’s command-line arguments from std::env::args.

This is the most common way to create a parser for typical CLI applications. The first argument (program name) is consumed and can be accessed via Parser::name.

§Errors

Returns ParsingError::Empty if no arguments are available (which should not happen in normal program execution).

§Examples
use sap::Parser;

let parser = Parser::from_env().unwrap();
println!("Program name: {}", parser.name());
Source§

impl<I, V> Parser<I>
where I: Iterator<Item = V>, V: Into<String>,

Source

pub fn from_arbitrary<A>(iter: A) -> Result<Parser<I>>
where A: IntoIterator<IntoIter = I>,

Creates a Parser from any iterator that yields items convertible to String.

This method provides maximum flexibility for parsing argument lists. You can pass string arrays, vectors, or any other iterable collection of string-like items. This is particularly useful for testing and when arguments come from sources other than the command line.

The first item from the iterator is treated as the program name and can be accessed via Parser::name. All subsequent items are parsed as arguments.

§Errors

Returns ParsingError::Empty if the iterator is empty.

§Examples
use sap::Parser;

// Parse from string arrays directly
let parser = Parser::from_arbitrary(["myprogram", "-v", "file.txt"]).unwrap();
assert_eq!(parser.name(), "myprogram");

// Also works with vectors of strings
let args = vec!["prog".to_string(), "--verbose".to_string()];
let parser = Parser::from_arbitrary(args).unwrap();
Source

pub fn forward(&mut self) -> Result<Option<Argument<'_>>>

Advances the parser to the next argument and returns it.

This is the main parsing method. Call it repeatedly to process all arguments. The parser maintains state between calls to properly handle complex scenarios like combined short options (-abc) and option values.

§Returns
  • Some(arg) - Successfully parsed the next argument
  • None - No more arguments to process
§Errors

Returns an error when:

  • Short options have attached values using = (e.g., -x=value)
  • Option values are left unconsumed from previous calls
  • Invalid argument syntax is encountered

Important: The parser should not be used after encountering an error. The internal state becomes undefined and further parsing may produce incorrect results.

§Examples
use sap::{Parser, Argument};

let mut parser = Parser::from_arbitrary(["prog", "-abc", "--file=test.txt"]).unwrap();

// Combined short options are parsed individually
assert_eq!(parser.forward().unwrap(), Some(Argument::Short('a')));
assert_eq!(parser.forward().unwrap(), Some(Argument::Short('b')));
assert_eq!(parser.forward().unwrap(), Some(Argument::Short('c')));

// Long option with attached value
assert_eq!(parser.forward().unwrap(), Some(Argument::Long("file")));
assert_eq!(parser.value(), Some("test.txt".to_string()));

assert_eq!(parser.forward().unwrap(), None);
Source

pub fn value(&mut self) -> Option<String>

Retrieves and consumes the value associated with the most recent option.

Call this method after parsing a long option that may have an attached value (using --option=value syntax). The value is consumed and subsequent calls will return None until another option with a value is parsed.

§Returns
  • Some(value) - The option has an attached value
  • None - The option has no attached value or it was already consumed
§Examples
use sap::{Parser, Argument};

let mut parser = Parser::from_arbitrary(["prog", "--file=input.txt", "--verbose"]).unwrap();

// Option with attached value
assert_eq!(parser.forward().unwrap(), Some(Argument::Long("file")));
assert_eq!(parser.value(), Some("input.txt".to_string()));
assert_eq!(parser.value(), None); // Already consumed

// Option without value
assert_eq!(parser.forward().unwrap(), Some(Argument::Long("verbose")));
assert_eq!(parser.value(), None);
Source

pub fn ignore_value(&mut self)

Discards any value associated with the most recent option.

This is a convenience method that calls Parser::value and discards the result. Use this when you know an option might have a value but you don’t need it, preventing unconsumed value errors.

§Examples
use sap::{Parser, Argument};

let mut parser = Parser::from_arbitrary(["prog", "--debug=verbose"]).unwrap();

assert_eq!(parser.forward().unwrap(), Some(Argument::Long("debug")));
parser.ignore_value(); // Discard the "verbose" value
Source

pub fn name(&self) -> &str

Returns the program name (the first argument from the iterator).

This is typically the name or path of the executable, depending on how the program was invoked.

§Examples
use sap::Parser;

let parser = Parser::from_arbitrary(["/usr/bin/myprogram", "-v"]).unwrap();
assert_eq!(parser.name(), "/usr/bin/myprogram");
Source

pub fn into_inner(self) -> I

Consumes the parser and returns the underlying iterator.

This allows access to any remaining, unparsed arguments. Note that the iterator’s state reflects the current parsing position.

§Examples
use sap::{Parser, Argument};

let mut parser = Parser::from_arbitrary(["prog", "-v", "remaining"]).unwrap();

// Parse one argument
parser.forward().unwrap();

// Get the remaining iterator
let remaining: Vec<String> = parser.into_inner().map(|s| s.into()).collect();
assert_eq!(remaining, vec!["remaining"]);

Auto Trait Implementations§

§

impl<I> Freeze for Parser<I>
where I: Freeze,

§

impl<I> RefUnwindSafe for Parser<I>
where I: RefUnwindSafe,

§

impl<I> Send for Parser<I>
where I: Send,

§

impl<I> Sync for Parser<I>
where I: Sync,

§

impl<I> Unpin for Parser<I>
where I: Unpin,

§

impl<I> UnwindSafe for Parser<I>
where I: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.