dia_args/lib.rs
1/*
2==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--
3
4Dia-Args
5
6Copyright (C) 2018-2019, 2021-2025 Anonymous
7
8There are several releases over multiple years,
9they are listed as ranges, such as: "2018-2019".
10
11This program is free software: you can redistribute it and/or modify
12it under the terms of the GNU Lesser General Public License as published by
13the Free Software Foundation, either version 3 of the License, or
14(at your option) any later version.
15
16This program is distributed in the hope that it will be useful,
17but WITHOUT ANY WARRANTY; without even the implied warranty of
18MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19GNU Lesser General Public License for more details.
20
21You should have received a copy of the GNU Lesser General Public License
22along with this program. If not, see <https://www.gnu.org/licenses/>.
23
24::--::--::--::--::--::--::--::--::--::--::--::--::--::--::--::--
25*/
26
27//! # A command line parser
28//!
29//! ## Project
30//!
31//! - License: GNU Lesser General Public License, either version 3, or (at your option) any later version.
32//! - _This project follows [Semantic Versioning 2.0.0]_
33//!
34//! ## Features
35//!
36//! - No debts. It's an argument parser, so standard Rust is enough.
37//! - [`parse_file()`][fn:parse_file] helps parse arguments stored in your file.
38//! - [`docs`][mod:docs] helps make documentation for your program.
39//! - Optional `bin` feature provides a program which helps you generate simple Rust source code templates. You can run the program with `help`
40//! command for more details.
41//!
42//! ## Specification
43//!
44//! A program argument can be:
45//!
46//! - A command.
47//! - An argument.
48//! - An option.
49//! - A special phrase: `--`.
50//!
51//! 1. Commands
52//!
53//! - A command can be anything which does not start with either `-` or `--`.
54//!
55//! 2. Arguments
56//!
57//! - Same as a command, an argument can be anything which does not start with either `-` or `--`.
58//!
59//! 3. Options
60//!
61//! An option starts with `-` or `--`.
62//!
63//! - `-` supports a single short format option.
64//!
65//! - `--` supports a single long format option.
66//!
67//! - Option values can be anything.
68//!
69//! - An option's key and value can be separated by either:
70//!
71//! + An equals sign `=`.
72//! + Or mutiple white spaces.
73//!
74//! - A boolean option has 2 values: `true` and `false`. The value is optional. If absent, `true` will be assigned.
75//!
76//! 4. Special phrases
77//!
78//! - `--` means: the program should process _all_ phrases after it _as_ arguments. This is normally used to pass arguments to sub process.
79//!
80//! 5. Passing arguments to a program
81//!
82//! Must be in this form:
83//!
84//! ```shell
85//! program [command|arguments...|options...|-] [-- [arguments...]]
86//! ```
87//!
88//! in which:
89//!
90//! - `[]` means optional.
91//! - `...` means multiple arguments.
92//!
93//! [Semantic Versioning 2.0.0]: https://semver.org/spec/v2.0.0.html
94//! [fn:parse_file]: fn.parse_file.html
95//! [mod:docs]: docs/index.html
96
97#![warn(missing_docs)]
98
99#![allow(clippy::bool_comparison)]
100#![allow(clippy::cognitive_complexity)]
101#![allow(clippy::match_bool)]
102
103// ╔═════════════════╗
104// ║ IDENTIFIERS ║
105// ╚═════════════════╝
106
107macro_rules! code_name { () => { "dia-args" }}
108macro_rules! version { () => { "0.61.0" }}
109
110/// # Crate name
111pub const NAME: &str = "Dia-Args";
112
113/// # Crate code name
114pub const CODE_NAME: &str = code_name!();
115
116/// # ID of this crate
117pub const ID: &str = concat!(
118 "881363a1-edf78ee6-1a07caa3-69118fdf-002b2e83-90f3078c-17337cb6-ea8745ad-",
119 "e2476d90-f5d89bf2-bad05032-561e9260-94b91133-3a7a18a0-37f88fd8-b4c8ec0c",
120);
121
122/// # Crate version
123pub const VERSION: &str = version!();
124
125/// # Crate release date (year/month/day)
126pub const RELEASE_DATE: (u16, u8, u8) = (2025, 3, 24);
127
128/// # Tag, which can be used for logging...
129pub const TAG: &str = concat!(code_name!(), "::881363a1::", version!());
130
131// ╔════════════════════╗
132// ║ IMPLEMENTATION ║
133// ╚════════════════════╝
134
135extern crate alloc;
136
137/// # Wrapper for format!(), which prefixes your optional message with: crate::TAG, module_path!(), line!()
138macro_rules! __ {
139 ($($arg: tt)+) => {
140 format!("[{tag}][{module_path}-{line}] {msg}", tag=$crate::TAG, module_path=module_path!(), line=line!(), msg=format!($($arg)+))
141 };
142 () => {
143 __!("(internal error)")
144 };
145}
146
147/// # Makes new std::io::Error
148macro_rules! err {
149 ($kind: path, $($arg: tt)+) => { std::io::Error::new($kind, __!($($arg)+)) };
150 ($($arg: tt)+) => { err!(std::io::ErrorKind::Other, $($arg)+) };
151 () => { std::io::Error::new(std::io::ErrorKind::Other, __!()) };
152}
153
154#[test]
155fn test_crate_version() {
156 assert_eq!(VERSION, env!("CARGO_PKG_VERSION"));
157}
158
159mod __;
160mod args;
161mod ask;
162mod merge_option;
163mod read_only_u64;
164
165pub mod docs;
166pub mod licenses;
167pub mod paths;
168pub mod version_info;
169
170pub use self::{
171 __::*,
172 args::*,
173 ask::*,
174 merge_option::*,
175};
176
177/// # Result type used in this crate
178pub type Result<T> = core::result::Result<T, std::io::Error>;
179
180/// # Default file name for storing arguments: `.dia-args`
181///
182/// The file must be placed within the directory of the program. Then you can use [`parse_file()`][fn:parse_file] to parse it. Refer to
183/// that function for content syntax.
184///
185/// [fn:parse_file]: fn.parse_file.html
186pub const DIA_ARGS_FILE_NAME: &str = concat!('.', code_name!());
187
188/// # Maximum size allowed for argument file to be parsed (3 MiB)
189pub const MAX_DIA_ARGS_FILE_SIZE: u64 = 3 * 1024 * 1024;
190
191#[test]
192fn tests() {
193 assert_eq!(DIA_ARGS_FILE_NAME, ".dia-args");
194}