dia-args 0.59.4

For handling command line arguments
Documentation
/*
==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--

Dia-Args

Copyright (C) 2018-2019, 2021-2023  Anonymous

There are several releases over multiple years,
they are listed as ranges, such as: "2018-2019".

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with this program.  If not, see <https://www.gnu.org/licenses/>.

::--::--::--::--::--::--::--::--::--::--::--::--::--::--::--::--
*/

//! # A command line parser
//!
//! ## Project
//!
//! - Repository: <https://bitbucket.org/de-marco/dia-args>
//! - License: GNU Lesser General Public License, either version 3, or (at your option) any later version.
//! - _This project follows [Semantic Versioning 2.0.0]_
//!
//! ## Features
//!
//! - No debts: no dependencies. It's an argument parser, so standard Rust is enough.
//! - There's a specification (below). It has a ***separate*** version, not same as the library's.
//! - [`parse_file()`][fn:parse_file] helps parse arguments stored in your file.
//! - [`docs`][mod:docs] helps make documentation for your program.
//! - Optional `bin` feature provides a program which helps you generate simple Rust source code templates. You can run the program with `help`
//!   command for more details.
//!
//! ## Specification `0.0.1`
//!
//! A program argument can be:
//!
//! - A command.
//! - An argument.
//! - An option.
//! - Two special phrases: `-` and `--`.
//!
//! 1. Commands
//!
//!    - A command can be anything which does not start with either `-` or `--`.
//!
//! 2. Arguments
//!
//!    - Same as a command, an argument can be anything which does not start with either `-` or `--`.
//!
//! 3. Options
//!
//!    An option starts with `-` or `--`.
//!
//!    - `-` supports either:
//!
//!        + A single short format option.
//!        + Or multiple short format _boolean_ options.
//!
//!    - `--` supports a single long format option.
//!
//!    - Option values can be anything.
//!
//!    - An option's key and value can be separated by either:
//!
//!        + An equals sign `=`.
//!        + Or mutiple white spaces.
//!
//!    - A boolean option has 2 values: `true` and `false`. The value is optional. If absent, `true` will be assigned.
//!
//! 4. Special phrases
//!
//!    - `-` means: the program should process standard input.
//!    - `--` means: the program should process _all_ phrases after it _as_ arguments. This is normally used to pass arguments to sub process.
//!
//! 5. Passing arguments to a program
//!
//!    Must be in this form:
//!
//!    ```shell
//!    program [command|arguments...|options...|-] [-- [arguments...]]
//!    ```
//!
//!    in which:
//!
//!    - `[]` means optional.
//!    - `...` means multiple arguments.
//!
//! [Semantic Versioning 2.0.0]: https://semver.org/spec/v2.0.0.html
//! [fn:parse_file]: fn.parse_file.html
//! [mod:docs]: docs/index.html

#![warn(missing_docs)]

#![allow(clippy::bool_comparison)]
#![allow(clippy::cognitive_complexity)]
#![allow(clippy::match_bool)]

// ╔═════════════════╗
// ║   IDENTIFIERS   ║
// ╚═════════════════╝

macro_rules! code_name  { () => { "dia-args" }}
macro_rules! version    { () => { "0.59.4" }}

/// # Crate name
pub const NAME: &str = "Dia-Args";

/// # Crate code name
pub const CODE_NAME: &str = code_name!();

/// # ID of this crate
pub const ID: &str = concat!(
    "881363a1-edf78ee6-1a07caa3-69118fdf-002b2e83-90f3078c-17337cb6-ea8745ad-",
    "e2476d90-f5d89bf2-bad05032-561e9260-94b91133-3a7a18a0-37f88fd8-b4c8ec0c",
);

/// # Crate version
pub const VERSION: &str = version!();

/// # Crate release date (year/month/day)
pub const RELEASE_DATE: (u16, u8, u8) = (2023, 1, 27);

/// # Tag, which can be used for logging...
pub const TAG: &str = concat!(code_name!(), "::881363a1::", version!());

// ╔════════════════════╗
// ║   IMPLEMENTATION   ║
// ╚════════════════════╝

/// # Wrapper for format!(), which prefixes your message with: crate::TAG, module_path!(), line!()
macro_rules! __ { ($($arg: tt)+) => {
    format!("[{tag}][{module_path}-{line}] {fmt}", tag=crate::TAG, module_path=module_path!(), line=line!(), fmt=format!($($arg)+))
};}

#[test]
fn test_crate_version() {
    assert_eq!(VERSION, env!("CARGO_PKG_VERSION"));
}

mod __;
mod args;
mod ask;
mod merge_option;
mod read_only_u64;

pub mod docs;
pub mod licenses;
pub mod paths;
pub mod version_info;

pub use self::{
    __::*,
    args::*,
    ask::*,
    merge_option::*,
};

/// # Result type used in this crate
pub type Result<T> = core::result::Result<T, std::io::Error>;

/// # Default file name for storing arguments: `.dia-args`
///
/// 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
/// that function for content syntax.
///
/// [fn:parse_file]: fn.parse_file.html
pub const DIA_ARGS_FILE_NAME: &str = concat!('.', code_name!());

/// # Maximum size allowed for argument file to be parsed (3 MiB)
pub const MAX_DIA_ARGS_FILE_SIZE: u64 = 3 * 1024 * 1024;

#[test]
fn tests() {
    assert_eq!(DIA_ARGS_FILE_NAME, ".dia-args");
}