clish 0.1.0-beta.1

Elegant CLI framework for Rust.
Documentation
#![deny(clippy::all)]
#![warn(missing_docs)]

//! # clish
//!
//! The most elegant CLI framework for Rust.
//!
//! Inspired by Typer. Define commands as plain functions. The argument types
//! determine how each parameter is parsed from the command line. Validation,
//! help generation, and error reporting are automatic.
//!
//! ```rust
//! use clish::prelude::*;
//!
//! #[command]
//! /// Deploy the application
//! fn deploy(target: Pos<String>, env: Named<String>, force: bool) {
//!     println!("Deploying {} to {}", target, env);
//! }
//!
//! fn main() {
//!     app!().run();
//! }
//! ```
//!
//! # Argument types
//!
//! |         Type          |          Behavior         | Example |
//! |-----------------------|---------------------------|---|
//! | [`Pos<T>`]            | Positional, required      | `myapp cmd foo` |
//! | [`Pos<Option<T>>`]    | Positional, optional      | `myapp cmd` or `myapp cmd foo` |
//! | [`Pos<Vec<T>>`]       | Positional, variadic      | `myapp cmd a b c` |
//! | [`Named<T>`]          | `--name val`, required    | `myapp cmd --env prod` |
//! | [`Named<Option<T>>`]  | `--name val`, optional    | |
//! | [`Named<Vec<T>>`]     | `--name val`, repeatable  | `myapp cmd --tag a --tag b` |
//! | `bool`                | `--flag` presence         | `myapp cmd --force` |
//!
//! `T` must implement [`FromStr`](std::str::FromStr). Type mismatches produce colored errors
//! at runtime. Invalid type combinations (`Option<Vec<T>>`, `Option<bool>`)
//! are rejected at compile time.
//!
//! # Re-exports
//!
//! This crate re-exports everything you need from `clish-core` and `clish-macros`.
//! See [`prelude`] for a single-use convenience import.

pub use clish_core::app::App;
pub use clish_core::help;
pub use clish_core::parse::ErrorKind;
pub use clish_core::types::{Flag, Named, Pos};
pub use clish_macros::command;

#[doc(hidden)]
pub use clish_core::inventory;
#[doc(hidden)]
pub use clish_core::parse;
#[doc(hidden)]
pub use clish_core::parse::CommandEntry;

/// Convenience module for a single `use` import.
///
/// ```rust
/// use clish::prelude::*;
/// ```
///
/// Re-exports: [`App`], [`Flag`], [`Named`], [`Pos`], [`app!`](crate::app),
/// [`command`].
pub mod prelude {
    pub use crate::{App, Flag, Named, Pos, app, command};
}

/// Construct an [`App`] with metadata from `Cargo.toml`.
///
/// Reads `CARGO_PKG_NAME`, `CARGO_PKG_VERSION`, and `CARGO_PKG_DESCRIPTION`
/// at compile time. Override any field with the builder methods on [`App`]:
///
/// ```rust
/// use clish::prelude::*;
///
/// app!()
///     .name("myapp")
///     .version("1.0.0")
///     .description("Does things.")
///     .details("Longer description shown on --help.")
///     .run();
/// ```
#[macro_export]
macro_rules! app {
    () => {
        $crate::App {
            name: env!("CARGO_PKG_NAME"),
            version: env!("CARGO_PKG_VERSION"),
            description: env!("CARGO_PKG_DESCRIPTION"),
            details: "",
            styles: $crate::help::HelpStyles::default(),
        }
    };
}