anpcli/
lib.rs

1//! # The AnpCLI Library
2//!
3//! The AnpCLI library provides an API for parsing command line options.
4//! It also able to print help message to show available options.
5//!
6//! The AnpCLI is simple, easy to learn and use but also highly customizable.
7//! It's inspired by the Java library - Apache Commons CLI.
8//!
9//! AnpCLI supports different types of options:
10//!
11//! - POSIX like options, for example `tar -zxvf foo.tar.gz`
12//! - GNU like long options, for example `du --human-readable --max-depth=1`
13//! - Short options with value attached, for example `gcc -O2 foo.c`
14//! - Long options with single hyphen, for example `ant -projecthelp`
15//!
16//! A typical help message displayed by AnpCLI looks like this:
17//!
18//! ```txt
19//! usage: ls
20//!  -A,--almost-all          do not list implied . and ..
21//!  -a,--all                 do not hide entries starting with .
22//!  -B,--ignore-backups      do not list implied entried ending with ~
23//!  -b,--escape              print octal escapes for nongraphic characters
24//!  --block-size <SIZE>      use SIZE-byte blocks
25//!  -c                       with -lt: sort by, and show, ctime (time of last
26//!                           modification of file status information) with
27//!                           -l:show ctime and sort by name otherwise: sort
28//!                           by ctime
29//!  -C                       list entries by columns
30//! ```
31//!
32//! # Examples
33//!
34//! A simple example.
35//!
36//! ```
37//! use anpcli::{AnpOption, Parser, DefaultParser, HelpFormatter, Options};
38//!
39//! let mut options = Options::new();
40//! options.add_option2("A", "almost-all", false, "do not list implied . and ..").unwrap();
41//! options.add_option2("a", "all", false, "do not hide entries starting with .").unwrap();
42//! options.add_option(AnpOption::builder()
43//!                     .long_option("block-size")
44//!                     .arg_name("SIZE")
45//!                     .has_arg(true)
46//!                     .desc("use SIZE-byte blocks")
47//!                     .build().unwrap());
48//!
49//! let mut formatter = HelpFormatter::new("ls");
50//! let mut parser = DefaultParser::builder().build();
51//! let cmd = parser.parse_or_exit(&options, &formatter);
52//!
53//! println!("almost-all: {}", cmd.has_option("almost-all"));
54//! println!("all: {}", cmd.has_option("all"));
55//! if cmd.has_option("block-size") {
56//!     println!("block-size: {}", cmd.get_expected_value::<usize>("block-size"));
57//! }
58//! ```
59//!
60//! A more complicated example.
61//!
62//! ```
63//! use std::io::stdout;
64//! use std::process::exit;
65//! use std::time::SystemTime;
66//! use anpcli::{AnpOption, Parser, DefaultParser, HelpFormatter, Options};
67//!
68//! let mut options = Options::new();
69//! options.add_option1("d", "show datetime").unwrap();
70//! options.add_option(AnpOption::builder()
71//!     .long_option("log-level")
72//!     .number_of_args(1)
73//!     .required(false)
74//!     .optional_arg(false)
75//!     .desc("The level of log to print in console")
76//!     .build().unwrap());
77//!
78//! let mut formatter = HelpFormatter::new("<file> [<file> ...]");
79//! formatter.set_auto_usage(true);
80//! formatter.set_header("A file processing tool.");
81//!
82//! let mut parser = DefaultParser::builder().build();
83//! let cmd = parser.parse_args(&options, &vec!["file_tool", "demo.txt", "main.txt"]);
84//!
85//! if cmd.is_err() {
86//!     eprintln!("parse error: {}", cmd.unwrap_err());
87//!     exit(1);
88//! }
89//! let cmd = cmd.unwrap();
90//!
91//! let files = cmd.get_arg_list();
92//! if files.len() <= 1 {
93//!     eprintln!("missing option <file>");
94//!     formatter.print_help(&mut stdout(), &options);
95//!     exit(1);
96//! } else {
97//!     println!("processing file: {:?}", &files[1..]);
98//! }
99//! if cmd.has_option("d") {
100//!     let datetime = SystemTime::now()
101//!                     .duration_since(SystemTime::UNIX_EPOCH)
102//!                     .unwrap().as_millis();
103//!     println!("datetime={}", datetime);
104//! }
105//! if cmd.has_option("log-level") {
106//!     let log_level = cmd.get_expected_value::<String>("log-level");
107//!     println!("log-level={}", log_level);
108//! }
109//! ```
110
111pub use cmd::CommandLine;
112pub use error::ParseErr;
113pub use format::HelpFormatter;
114pub use option::{AnpOption, OptionBuilder, OptionGroup, Options};
115pub use parser::{DefaultParser, Parser, ParserBuilder};
116
117mod format;
118mod util;
119mod option;
120mod cmd;
121mod parser;
122mod error;