paw/lib.rs
1#![forbid(unsafe_code, future_incompatible)]
2#![deny(missing_debug_implementations, bad_style)]
3#![warn(missing_docs)]
4#![cfg_attr(test, deny(warnings))]
5
6//! Command line argument paw-rser abstraction for main.
7//!
8//! Paw's goal is to show that C's idea of passing arguments into main wasn't that
9//! bad at all, but just needed a bit of oxidation to make it work with Rust.
10//!
11//! Paw defines a trait, a proc macro, and an example implementation that when
12//! combined allow you to pass fully parsed arguments to main. Gone is the need to
13//! remember which methods to call in order to parse arguments in the CLI. Instead
14//! paw makes command line parsing feel first-class
15//!
16//! ## Examples
17//! __Create a parser from scratch__
18//! ```rust
19//! #[paw::main]
20//! fn main(args: paw::Args) {
21//! for arg in args {
22//! println!("{:?}", arg);
23//! }
24//! }
25//! ```
26//!
27//! To start the server do:
28//! ```sh
29//! $ cargo run --example scratch -- localhost 8080
30//! ```
31//!
32//! __More Examples__
33//! - [Scratch](https://github.com/rust-cli/paw/tree/master/examples/scratch.rs)
34//! - [Args](https://github.com/rust-cli/paw/tree/master/examples/args.rs)
35//! - [Structopt](https://github.com/rust-cli/paw/tree/master/examples/structopt.rs)
36
37use std::env::{Args as StdArgs, ArgsOs as StdArgsOs};
38use std::ffi::OsString;
39use std::fmt;
40use std::iter::Iterator;
41
42#[doc(inline)]
43#[cfg(not(test))] // NOTE: exporting main breaks tests, we should file an issue.
44pub use paw_attributes::main;
45
46#[doc(inline)]
47pub use paw_raw::ParseArgs;
48
49/// An iterator over the arguments of a process, yielding an [`String`] value for each argument.
50///
51/// This is a wrapper over [`std::env::Args`] which is an iterator over the arguments to a process.
52/// See its documentation for more.
53///
54/// [`String`]: ../string/struct.String.html
55/// [`std::env::Args`]: https://doc.rust-lang.org/std/env/struct.Args.html
56pub struct Args {
57 inner: StdArgs,
58}
59
60impl fmt::Debug for Args {
61 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
62 self.inner.fmt(f)
63 }
64}
65
66impl Iterator for Args {
67 type Item = String;
68
69 fn next(&mut self) -> Option<Self::Item> {
70 self.inner.next()
71 }
72}
73
74impl ExactSizeIterator for Args {
75 fn len(&self) -> usize {
76 self.inner.len()
77 }
78}
79
80impl DoubleEndedIterator for Args {
81 fn next_back(&mut self) -> Option<String> {
82 self.inner.next_back()
83 }
84}
85
86impl ParseArgs for Args {
87 type Error = std::io::Error;
88 fn parse_args() -> Result<Self, Self::Error> {
89 Ok(Self {
90 inner: std::env::args(),
91 })
92 }
93}
94
95/// An iterator over the arguments of a process, yielding an [`OsString`] value for each argument.
96///
97/// This is a wrapper over [`std::env::ArgsOs`] which is an iterator over the arguments to a
98/// process. See its documentation for more.
99///
100/// [`OsString`]: ../ffi/struct.OsString.html
101/// [`std::env::ArgsOs`]: https://doc.rust-lang.org/std/env/struct.ArgsOs.html
102pub struct ArgsOs {
103 inner: StdArgsOs,
104}
105
106impl fmt::Debug for ArgsOs {
107 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
108 self.inner.fmt(f)
109 }
110}
111
112impl Iterator for ArgsOs {
113 type Item = OsString;
114
115 fn next(&mut self) -> Option<Self::Item> {
116 self.inner.next()
117 }
118}
119
120impl ExactSizeIterator for ArgsOs {
121 fn len(&self) -> usize {
122 self.inner.len()
123 }
124}
125
126impl DoubleEndedIterator for ArgsOs {
127 fn next_back(&mut self) -> Option<OsString> {
128 self.inner.next_back()
129 }
130}
131
132impl ParseArgs for ArgsOs {
133 type Error = std::io::Error;
134 fn parse_args() -> Result<Self, Self::Error> {
135 Ok(Self {
136 inner: std::env::args_os(),
137 })
138 }
139}