summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mingling/Cargo.lock146
-rw-r--r--mingling/Cargo.toml2
-rw-r--r--mingling/src/lib.rs165
3 files changed, 313 insertions, 0 deletions
diff --git a/mingling/Cargo.lock b/mingling/Cargo.lock
index edb7731..582c464 100644
--- a/mingling/Cargo.lock
+++ b/mingling/Cargo.lock
@@ -18,12 +18,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33"
[[package]]
+name = "cfg-if"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
+
+[[package]]
name = "equivalent"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
[[package]]
+name = "errno"
+version = "0.3.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
+dependencies = [
+ "libc",
+ "windows-sys",
+]
+
+[[package]]
name = "hashbrown"
version = "0.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -52,6 +68,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5454cda0d57db59778608d7a47bff5b16c6705598265869fb052b657f66cf05e"
[[package]]
+name = "libc"
+version = "0.2.184"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "48f5d2a454e16a5ea0f4ced81bd44e4cfc7bd3a507b61887c99fd3538b28e4af"
+
+[[package]]
+name = "lock_api"
+version = "0.4.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965"
+dependencies = [
+ "scopeguard",
+]
+
+[[package]]
name = "memchr"
version = "2.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -66,6 +97,7 @@ dependencies = [
"mingling_macros",
"serde",
"size",
+ "tokio",
]
[[package]]
@@ -94,12 +126,46 @@ dependencies = [
]
[[package]]
+name = "mio"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1"
+dependencies = [
+ "libc",
+ "wasi",
+ "windows-sys",
+]
+
+[[package]]
name = "once_cell"
version = "1.21.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
[[package]]
+name = "parking_lot"
+version = "0.12.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a"
+dependencies = [
+ "lock_api",
+ "parking_lot_core",
+]
+
+[[package]]
+name = "parking_lot_core"
+version = "0.9.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "redox_syscall",
+ "smallvec",
+ "windows-link",
+]
+
+[[package]]
name = "pin-project-lite"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -124,6 +190,15 @@ dependencies = [
]
[[package]]
+name = "redox_syscall"
+version = "0.5.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d"
+dependencies = [
+ "bitflags",
+]
+
+[[package]]
name = "ron"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -144,6 +219,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f"
[[package]]
+name = "scopeguard"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
+
+[[package]]
name = "serde"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -209,12 +290,38 @@ dependencies = [
]
[[package]]
+name = "signal-hook-registry"
+version = "1.4.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b"
+dependencies = [
+ "errno",
+ "libc",
+]
+
+[[package]]
name = "size"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b6709c7b6754dca1311b3c73e79fcce40dd414c782c66d88e8823030093b02b"
[[package]]
+name = "smallvec"
+version = "1.15.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
+
+[[package]]
+name = "socket2"
+version = "0.6.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e"
+dependencies = [
+ "libc",
+ "windows-sys",
+]
+
+[[package]]
name = "syn"
version = "2.0.117"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -252,7 +359,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "27ad5e34374e03cfffefc301becb44e9dc3c17584f414349ebe29ed26661822d"
dependencies = [
"bytes",
+ "libc",
+ "mio",
+ "parking_lot",
"pin-project-lite",
+ "signal-hook-registry",
+ "socket2",
+ "tokio-macros",
+ "windows-sys",
+]
+
+[[package]]
+name = "tokio-macros"
+version = "2.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c55a2eff8b69ce66c84f85e1da1c233edc36ceb85a2058d11b0d6a3c7e7569c"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
]
[[package]]
@@ -313,6 +438,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861"
[[package]]
+name = "wasi"
+version = "0.11.1+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
+
+[[package]]
+name = "windows-link"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
+
+[[package]]
+name = "windows-sys"
+version = "0.61.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
+dependencies = [
+ "windows-link",
+]
+
+[[package]]
name = "winnow"
version = "0.7.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/mingling/Cargo.toml b/mingling/Cargo.toml
index a915fea..30a004b 100644
--- a/mingling/Cargo.toml
+++ b/mingling/Cargo.toml
@@ -11,6 +11,8 @@ categories = ["command-line-interface"]
repository = "https://github.com/catilgrass/mingling"
[dev-dependencies]
+serde = { version = "1", features = ["derive"] }
+tokio = { version = "1", features = ["full"] }
mingling = { path = ".", features = ["full"] }
[features]
diff --git a/mingling/src/lib.rs b/mingling/src/lib.rs
index 1d54140..dcb9dd0 100644
--- a/mingling/src/lib.rs
+++ b/mingling/src/lib.rs
@@ -49,6 +49,10 @@
//! > mycmd hallo
//! Dispatcher not found for command `hallo`
//! ```
+//!
+//! # Features
+//! - `parser` enables the `mingling::parser` module [More](./docs/parser/index.html)
+//! - `general_renderer` adds support for serialized output formats such as JSON and YAML
// Re-export Core lib
pub use mingling::*;
@@ -82,3 +86,164 @@ pub mod macros {
/// Used to generate a struct implementing the `Renderer` trait via a method
pub use mingling_macros::renderer;
}
+
+pub mod docs {
+ pub mod basic {
+ //! # Basic Usage
+ //!
+ //! This module demonstrates basic usage of Mingling with a simple "hello" command.
+ //!
+ //! ## Example
+ //!
+ //! ```rust
+ //! use mingling::{
+ //! macros::{chain, dispatcher, gen_program, pack, r_println, renderer},
+ //! marker::NextProcess,
+ //! };
+ //!
+ //! // Define dispatcher `HelloCommand`, directing subcommand "hello" to `HelloEntry`
+ //! dispatcher!("hello", HelloCommand => HelloEntry);
+ //!
+ //! #[tokio::main]
+ //! async fn main() {
+ //! // Create program
+ //! let mut program = DefaultProgram::new();
+ //!
+ //! // Add dispatcher `HelloCommand`
+ //! program.with_dispatcher(HelloCommand);
+ //!
+ //! // Run program
+ //! program.exec().await;
+ //! }
+ //!
+ //! // Register wrapper type `Hello`, setting inner to `String`
+ //! pack!(Hello = String);
+ //!
+ //! // Register chain to `DefaultProgram`, handling logic from `HelloEntry`
+ //! #[chain]
+ //! async fn parse_name(prev: HelloEntry) -> NextProcess {
+ //! // Extract string from `HelloEntry` as argument
+ //! let name = prev.get(0).cloned().unwrap_or_else(|| "World".to_string());
+ //!
+ //! // Build `Hello` type and route to renderer
+ //! Hello::new(name).to_render()
+ //! }
+ //!
+ //! // Register renderer to `DefaultProgram`, handling rendering of `Hello`
+ //! #[renderer]
+ //! fn render_hello_who(prev: Hello) {
+ //! // Print message
+ //! r_println!("Hello, {}!", *prev);
+ //!
+ //! // Program ends here
+ //! }
+ //!
+ //! // Generate program, default is `DefaultProgram`
+ //! gen_program!();
+ //! ```
+ //!
+ //! ## Output
+ //!
+ //! ```text
+ //! > mycmd hello
+ //! Hello, World!
+ //! > mycmd hello Alice
+ //! Hello, Alice!
+ //! ```
+ }
+
+ pub mod parser {
+ //! # Feature `parser` Usage
+ //!
+ //! This module demonstrates advanced usage of Mingling with the `Picker` utility for argument parsing.
+ //!
+ //! ## Example
+ //!
+ //! ```rust
+ //! use mingling::{
+ //! AnyOutput,
+ //! macros::{chain, dispatcher, gen_program, pack, r_println, renderer},
+ //! marker::NextProcess,
+ //! parser::Picker,
+ //! };
+ //!
+ //! // Define dispatcher `RepeatCommand`, directing subcommand "repeat" to `RepeatEntry`
+ //! dispatcher!("repeat", RepeatCommand => RepeatEntry);
+ //!
+ //! #[tokio::main]
+ //! async fn main() {
+ //! // Create program
+ //! let mut program = DefaultProgram::new();
+ //!
+ //! // Add dispatcher `RepeatCommand`
+ //! program.with_dispatcher(RepeatCommand);
+ //!
+ //! // Run program
+ //! program.exec().await;
+ //! }
+ //!
+ //! // Register wrapper type `RepeatArgument`, setting inner to `(i32, String)`
+ //! pack!(RepeatArgument = (i32, String));
+ //!
+ //! // Register error type
+ //! pack!(ErrorContentRequired = ());
+ //!
+ //! // Register chain to `DefaultProgram`, handling logic for `RepeatEntry`
+ //! #[chain]
+ //! async fn parse_repeat_args(prev: RepeatEntry) -> NextProcess {
+ //! let picker = Picker::new(prev.inner); // Create Picker from user arguments
+ //! let picked = picker
+ //! .pick_or::<i32>("--time", 1) // Extract argument `--time`
+ //! .after(|n| n.clamp(1, 20)) // Clamp extracted number between 1 - 20
+ //! // Extract first remaining argument as content, route to type `ErrorContentRequired` if not found
+ //! .pick_or_route((), AnyOutput::new(ErrorContentRequired::default()))
+ //! .unpack(); // Unpack
+ //!
+ //! match picked {
+ //! Ok(args) => {
+ //! // Build `RepeatArgument` type and route to renderer
+ //! RepeatArgument::new(args).to_render()
+ //! }
+ //! Err(e) => {
+ //! // Extraction failed, route to error type
+ //! e.route_renderer()
+ //! }
+ //! }
+ //! }
+ //!
+ //! // Render `RepeatArgument`
+ //! #[renderer]
+ //! fn render_repeat(prev: RepeatArgument) {
+ //! let (times, content) = prev.inner;
+ //! for _ in 0..times {
+ //! r_println!("{}", content);
+ //! }
+ //! }
+ //!
+ //! // Render `ErrorContentRequired`
+ //! #[renderer]
+ //! fn render_error_content_required(_prev: ErrorContentRequired) {
+ //! r_println!("Error: content is required");
+ //! }
+ //!
+ //! // Generate program, default is `DefaultProgram`
+ //! gen_program!();
+ //! ```
+ //!
+ //! ## Output
+ //!
+ //! ```text
+ //! > mycmd repeat --time 3 Hello
+ //! Hello
+ //! Hello
+ //! Hello
+ //! > mycmd repeat --time 25 Hello
+ //! Hello
+ //! Hello
+ //! Hello
+ //! ... (repeated 20 times, clamped from 25)
+ //! > mycmd repeat --time 3
+ //! Error: content is required
+ //! ```
+ }
+}