Skip to content

Commit cc4a7cc

Browse files
authored
comment,doc: added the document comments (#6)
1 parent d008168 commit cc4a7cc

File tree

5 files changed

+271
-14
lines changed

5 files changed

+271
-14
lines changed

src/errors/arg_err.rs

+13-1
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,21 @@ use std::error;
66
use std::ffi;
77
use std::fmt;
88

9+
/// The enum type for errors of `OsString` arguments.
10+
///
11+
/// The variants of this enum indicates errors that can occur when operating
12+
/// command line arguments represented by `OsString`.
913
#[derive(Debug, PartialEq)]
1014
pub enum InvalidOsArg {
11-
OsArgsContainInvalidUnicode { index: usize, os_arg: ffi::OsString },
15+
/// The enum variant which indicates that at least one `OsString` value in
16+
/// the command line arguments is invalid Unicode.
17+
OsArgsContainInvalidUnicode {
18+
/// The index of the invalid argument.
19+
/// The argument of which index is zero is the command path.
20+
index: usize,
21+
/// The `OsString` value of the invalid argument.
22+
os_arg: ffi::OsString,
23+
},
1224
}
1325

1426
impl fmt::Display for InvalidOsArg {

src/errors/cfg_err.rs

+41-8
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,54 @@
55
use std::error;
66
use std::fmt;
77

8+
/// The enum type for errors of option configurations.
9+
///
10+
/// This enum type has `store_key()` method, which makes it possible to handle
11+
/// configuration-related errors in a unified manner.
812
#[derive(Debug, PartialEq)]
913
pub enum InvalidConfig {
10-
StoreKeyIsDuplicated { store_key: String },
11-
ConfigIsMultiArgsButHasNoArg { store_key: String },
12-
ConfigHasDefaultsButHasNoArg { store_key: String },
13-
OptionNameIsDuplicated { store_key: String, name: String },
14+
/// Indicates that there are duplicate store keys among multiple
15+
/// configurations.
16+
StoreKeyIsDuplicated {
17+
/// The store key of the specified option in the configuration.
18+
store_key: String,
19+
},
20+
21+
/// Indicates that an option configuration contradicts that the option can
22+
/// take multiple arguments (`.is_multi_args == true`) though it does not
23+
/// take option arguments (`.has_arg == false`).
24+
ConfigIsMultiArgsButHasNoArg {
25+
/// The store key of the specified option in the configuration.
26+
store_key: String,
27+
},
28+
29+
/// Indicates that an option configuration contradicts that the default
30+
/// arguments (`.defaults`) is not empty though it does not take option
31+
/// arguments (`has_arg == false`).
32+
ConfigHasDefaultsButHasNoArg {
33+
/// The store key of the specified option in the configuration.
34+
store_key: String,
35+
},
36+
37+
/// Indicates that there are duplicated option names among the option
38+
/// configurations.
39+
OptionNameIsDuplicated {
40+
/// The store key of the specified option in the configuration.
41+
store_key: String,
42+
43+
/// The option name that caused this error.
44+
name: String,
45+
},
1446
}
1547

1648
impl InvalidConfig {
49+
/// Returns the key used to store the option in the `Cmd` instance.
1750
pub fn store_key(&self) -> &str {
1851
return match self {
19-
InvalidConfig::StoreKeyIsDuplicated { store_key } => store_key,
20-
InvalidConfig::ConfigIsMultiArgsButHasNoArg { store_key } => store_key,
21-
InvalidConfig::ConfigHasDefaultsButHasNoArg { store_key } => store_key,
22-
InvalidConfig::OptionNameIsDuplicated { store_key, .. } => store_key,
52+
InvalidConfig::StoreKeyIsDuplicated { store_key } => &store_key,
53+
InvalidConfig::ConfigIsMultiArgsButHasNoArg { store_key } => &store_key,
54+
InvalidConfig::ConfigHasDefaultsButHasNoArg { store_key } => &store_key,
55+
InvalidConfig::OptionNameIsDuplicated { store_key, .. } => &store_key,
2356
};
2457
}
2558
}

src/errors/opt_err.rs

+49-5
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,60 @@
55
use std::error;
66
use std::fmt;
77

8+
/// The enum type for errors of options or option arguments.
9+
///
10+
/// This enum type has `option()` method, which makes it possible to handle
11+
/// option-related errors in a unified manner.
812
#[derive(Debug, PartialEq)]
913
pub enum InvalidOption {
10-
OptionContainsInvalidChar { option: String },
11-
UnconfiguredOption { option: String },
12-
OptionNeedsArg { option: String, store_key: String },
13-
OptionTakesNoArg { option: String, store_key: String },
14-
OptionIsNotMultiArgs { option: String, store_key: String },
14+
/// Indicates that the name of an option is using invalid characters.
15+
/// This error occurs if the name contains symbols or starts with a symbol
16+
/// or number.
17+
OptionContainsInvalidChar {
18+
/// The option name that caused this error.
19+
option: String,
20+
},
21+
22+
/// Indicates that the option with the specified name does not exist in the
23+
/// option configurations.
24+
UnconfiguredOption {
25+
/// The option name that caused this error.
26+
option: String,
27+
},
28+
29+
/// Indicates that the option requires arguments in the configuration, but
30+
/// no argument is specified.
31+
OptionNeedsArg {
32+
/// The option name that caused this error.
33+
option: String,
34+
35+
/// The store key of the specified option in the configuration.
36+
store_key: String,
37+
},
38+
39+
/// Indicates that the option is not suppoesed to take an argument in the
40+
/// configuration, but an argument is specified.
41+
OptionTakesNoArg {
42+
/// The option name that caused this error.
43+
option: String,
44+
45+
/// The store key of the specified option in the configuration.
46+
store_key: String,
47+
},
48+
49+
/// Indicates that the option is supposed to take one argument in the
50+
/// configuration, but multiple arguments are specified.
51+
OptionIsNotMultiArgs {
52+
/// The option name that caused this error.
53+
option: String,
54+
55+
/// The store key of the specified option in the configuration.
56+
store_key: String,
57+
},
1558
}
1659

1760
impl InvalidOption {
61+
/// Returns the name of the option that caused the error.
1862
pub fn option(&self) -> &str {
1963
return match self {
2064
InvalidOption::OptionContainsInvalidChar { option } => &option,

src/lib.rs

+148
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,110 @@
22
// This program is free software under MIT License.
33
// See the file LICENSE in this distribution for more details.
44

5+
//! This crate is a library to parse command line arguments.
6+
//!
7+
//! This crate provides the following functionalities:
8+
//!
9+
//! - Supports [POSIX][posix] & [GNU][gnu] like short and long options.
10+
//! - This crate supports `--` option.
11+
//! - This library doesn't support numeric short option.
12+
//! - This library supports not `-ofoo` but `-o=foo` as an alternative to
13+
//! `-o foo` for short option.
14+
//!
15+
//! [posix]: https://www.gnu.org/software/libc/manual/html_node/Argument-Syntax.html#Argument-Syntax
16+
//! [gnu]: https://www.gnu.org/prep/standards/html_node/Command_002dLine-Interfaces.html
17+
//!
18+
//! ## Install
19+
//!
20+
//! In `Cargo.toml`, write this crate as a dependency.
21+
//!
22+
//! ```toml
23+
//! [dependencies]
24+
//! cliargs = "0.1.0"
25+
//! ```
26+
//!
27+
//! ## Usage
28+
//!
29+
//! This crate provides the `Cmd` strcut to parse command line arguments.
30+
//! The usage of this `Cmd` struct is as follows:
31+
//!
32+
//! ### Creates a `Cmd` instance
33+
//!
34+
//! The `Cmd::new` function creates a `Cmd` instance with original command line
35+
//! arguments.
36+
//! This function uses `std::env::arg_os` and `OsString#into_string` to read
37+
//! command line arguments in order to avoid `panic!` call that the user cannot
38+
//! control.
39+
//!
40+
//! ```rust
41+
//! use cliargs::Cmd;
42+
//! use cliargs::errors::InvalidOsArg;
43+
//!
44+
//! let cmd = match Cmd::new() {
45+
//! Ok(cmd) => cmd,
46+
//! Err(InvalidOsArg::OsArgsContainInvalidUnicode { index, os_arg }) => {
47+
//! panic!("Invalid Unicode data: {:?} (index: {})", os_arg, index);
48+
//! }
49+
//! };
50+
//! ```
51+
//!
52+
//! ### Creates a `Cmd` instance with the specified `String` array
53+
//!
54+
//! The `Cmd::with_strings` function creates a `Cmd` instance with the
55+
//! specified `String` array.
56+
//!
57+
//! ```rust
58+
//! use cliargs::Cmd;
59+
//! use std::env;
60+
//!
61+
//! let cmd = Cmd::with_strings(env::args());
62+
//! ```
63+
//!
64+
//! ### Creates a `Cmd` instance with the specified `OsString` array.
65+
//!
66+
//! ```rust
67+
//! use cliargs::Cmd;
68+
//! use cliargs::errors::InvalidOsArg;
69+
//! use std::env;
70+
//!
71+
//! let cmd = match Cmd::with_os_strings(env::args_os()) {
72+
//! Ok(cmd) => cmd,
73+
//! Err(InvalidOsArg::OsArgsContainInvalidUnicode { index, os_arg }) => {
74+
//! panic!("Invalid Unicode data: {:?} (index: {})", os_arg, index);
75+
//! }
76+
//! };
77+
//! ```
78+
//!
79+
//! ## Parses without configurations
80+
//!
81+
//! The `Cmd` struct has the method which parses command line arguments without
82+
//! configurations.
83+
//! This method automatically divides command line arguments to options and
84+
//! command arguments.
85+
//!
86+
//! Command line arguments starts with `-` or `--` are options, and others are
87+
//! command arguments.
88+
//! If you want to specify a value to an option, follows `"="` and the value
89+
//! after the option, like `foo=123`.
90+
//!
91+
//! All command line arguments after `--` are command arguments, even they
92+
//! starts with `-` or `--`.
93+
//!
94+
//! ```rust
95+
//! use cliargs::Cmd;
96+
//! use cliargs::errors::InvalidOption;
97+
//!
98+
//! let mut cmd = Cmd::with_strings(vec![ /* ... */ ]);
99+
//! match cmd.parse() {
100+
//! Ok(_) => { /* ... */ },
101+
//! Err(InvalidOption::OptionContainsInvalidChar { option }) => {
102+
//! panic!("Option contains invalid character: {option}");
103+
//! },
104+
//! Err(err) => panic!("Invalid option: {}", err.option()),
105+
//! }
106+
//! ```
107+
108+
/// Enums for errors that can occur when parsing command line arguments.
5109
pub mod errors;
6110

7111
mod parse;
@@ -13,6 +117,15 @@ use std::fmt;
13117
use std::mem;
14118
use std::path;
15119

120+
/// `Cmd` is the struct that parses command line arguments and stores them.
121+
///
122+
/// The results of parsing are stored by separating into command name,
123+
/// command arguments, options, and option arguments.
124+
///
125+
/// These values are retrieved as string slices with the same lifetime as this
126+
/// `Cmd` instance.
127+
/// Therefore, if you want to use those values for a longer period, it is
128+
/// needed to convert them to [String]s.
16129
pub struct Cmd<'a> {
17130
name: &'a str,
18131
args: Vec<&'a str>,
@@ -41,10 +154,20 @@ impl fmt::Debug for Cmd<'_> {
41154
}
42155

43156
impl<'a> Cmd<'a> {
157+
/// Creates a `Cmd` instance with command line arguments obtained from
158+
/// [std::env::args_os].
159+
///
160+
/// Since [std::env::args_os] returns a vector of [OsString] and they can
161+
/// contain invalid unicode data, the return value of this funciton is
162+
/// [Result] of `Cmd` or `errors::InvalidOsArg`.
44163
pub fn new() -> Result<Cmd<'a>, errors::InvalidOsArg> {
45164
Self::with_os_strings(env::args_os())
46165
}
47166

167+
/// Creates a `Cmd` instance with the specified iterator of [OsString]s.
168+
///
169+
/// [OsString]s can contain invalid unicode data, the return value of
170+
/// this function is [Result] of `Cmd` or `errors::InvalidOsArg`.
48171
pub fn with_os_strings(
49172
osargs: impl IntoIterator<Item = OsString>,
50173
) -> Result<Cmd<'a>, errors::InvalidOsArg> {
@@ -113,6 +236,7 @@ impl<'a> Cmd<'a> {
113236
})
114237
}
115238

239+
/// Creates a `Cmd` instance with the specified iterator of [String]s.
116240
pub fn with_strings(args: impl IntoIterator<Item = String>) -> Cmd<'a> {
117241
let arg_iter = args.into_iter();
118242
let (size, _) = arg_iter.size_hint();
@@ -147,18 +271,34 @@ impl<'a> Cmd<'a> {
147271
}
148272
}
149273

274+
/// Returns the command name.
275+
///
276+
/// This name is base name extracted from the command path string slice,
277+
/// which is the first element of the command line arguments.
150278
pub fn name(&'a self) -> &'a str {
151279
self.name
152280
}
153281

282+
/// Returns the command arguments.
283+
///
284+
/// These arguments are retrieved as string slices in an array.
154285
pub fn args(&'a self) -> &'a [&'a str] {
155286
&self.args
156287
}
157288

289+
/// Checks whether an option with the specified name exists.
158290
pub fn has_opt(&self, name: &str) -> bool {
159291
self.opts.contains_key(name)
160292
}
161293

294+
/// Returns the option argument with the specified name.
295+
///
296+
/// If the option has multiple arguments, this method returns the first
297+
/// argument.
298+
///
299+
/// Since the option may not be specified in the command line arguments,
300+
/// the return value of this method is an [Option] of an option argument
301+
/// or [None].
162302
pub fn opt_arg(&'a self, name: &str) -> Option<&'a str> {
163303
if let Some(opt_vec) = self.opts.get(name) {
164304
if opt_vec.len() > 0 {
@@ -168,6 +308,14 @@ impl<'a> Cmd<'a> {
168308
None
169309
}
170310

311+
/// Returns the option arguments with the specified name.
312+
///
313+
/// If the option has one or multiple arguments, this method returns an
314+
/// array of the arguments.
315+
///
316+
/// Since the option may not be specified in the command line arguments,
317+
/// the return value of this method is an [Option] of option arguments or
318+
/// [None].
171319
pub fn opt_args(&'a self, name: &str) -> Option<&'a [&'a str]> {
172320
match self.opts.get(name) {
173321
Some(vec) => Some(&vec),

src/parse/parse.rs

+20
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,26 @@ use crate::errors::InvalidOption;
77
use crate::Cmd;
88

99
impl<'a> Cmd<'a> {
10+
/// Parses command line arguments without configurations.
11+
///
12+
/// This method divides command line arguments into options and command
13+
/// arguments based on imple rules that are almost the same as POSIX &
14+
/// GNU:
15+
/// arguments staring with `-` or `--` are treated as options, and
16+
/// others are treated as command arguments.
17+
/// If an `=` is found within an option, the part before the `=` is treated
18+
/// as the option name, and the part after the `=` is treated as the option
19+
/// argument.
20+
/// Options starting with `--` are long options and option starting with
21+
/// `-` are short options.
22+
/// Multiple short options can be concatenated into a single command line
23+
/// argument.
24+
/// If an argument is exactly `--`, all subsequent arguments are treated as
25+
/// command arguments.
26+
///
27+
/// Since the results of parsing are stored into this `Cmd` instance, this
28+
/// method returns a [Result] which contains an unit value (`()`) if
29+
/// succeeding, or a `errors::InvalidOption` if failing.
1030
pub fn parse(&mut self) -> Result<(), InvalidOption> {
1131
let collect_args = |arg| {
1232
self.args.push(arg);

0 commit comments

Comments
 (0)