aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md5
-rw-r--r--docs/README.md11
-rw-r--r--docs/pages/1-get-started.md32
-rw-r--r--docs/pages/2-basic/1-program.md15
-rw-r--r--docs/pages/2-basic/2-setup.md5
-rw-r--r--docs/pages/2-basic/3-dispatcher.md5
-rw-r--r--docs/pages/2-basic/4-chain.md13
-rw-r--r--docs/pages/2-basic/5-renderer.md9
-rw-r--r--docs/pages/3-features/1-parser.md20
-rw-r--r--docs/res/guide.txt2
-rw-r--r--mingling/src/example_docs.rs31
11 files changed, 61 insertions, 87 deletions
diff --git a/README.md b/README.md
index 628693e..2ef52f4 100644
--- a/README.md
+++ b/README.md
@@ -53,13 +53,12 @@ The example below shows how to use `Mingling` to create a simple command-line pr
```rust
use mingling::macros::{dispatcher, gen_program, r_println, renderer};
-#[tokio::main]
-async fn main() {
+fn main() {
let mut program = ThisProgram::new();
program.with_dispatcher(HelloCommand);
// Execute
- program.exec().await;
+ program.exec();
}
// Define command: "<bin> hello"
diff --git a/docs/README.md b/docs/README.md
index 016a4f7..8c698f0 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -53,13 +53,12 @@ The example below shows how to use `Mingling` to create a simple command-line pr
```rust
use mingling::macros::{dispatcher, gen_program, r_println, renderer};
-#[tokio::main]
-async fn main() {
+fn main() {
let mut program = ThisProgram::new();
program.with_dispatcher(HelloCommand);
// Execute
- program.exec().await;
+ program.exec();
}
// Define command: "<bin> hello"
@@ -139,11 +138,11 @@ You can read the following docs to learn more about the `Mingling` framework:
- [x] core: \[[0.1.4](https://docs.rs/mingling/0.1.4/mingling/)\] General Renderers *( Json, Yaml, Toml, Ron )*
- [x] core: \[[0.1.5](https://docs.rs/mingling/0.1.5/mingling/)\] Completion *( Bash Zsh Fish Pwsh )*
-- [ ] \[**0.1.6**\] Smarter Completion Suggest Generation
+- [ ] core: \[**0.1.6**\] Smarter Completion Suggest Generation
- [ ] \[**0.1.7**\] Clap Parser Support
-- [ ] \[**0.1.8**\] Faster Dispatcher
+- [ ] core: \[**0.1.8**\] Faster Dispatcher
- [ ] \[**0.1.9**\] Helpdoc Generation
-- [ ] \[**0.1.9**\] Debug Toolkits (InvokeStackDisplay ...)
+- [ ] core: \[**0.1.9**\] Debug Toolkits (InvokeStackDisplay ...)
- [ ] ...
- [ ] \[**unplanned**\] Parser Theme
- [ ] core: \[**unplanned**\] Parallel Chains
diff --git a/docs/pages/1-get-started.md b/docs/pages/1-get-started.md
index f4edfc0..b05e72b 100644
--- a/docs/pages/1-get-started.md
+++ b/docs/pages/1-get-started.md
@@ -9,24 +9,10 @@ cargo add mingling
Or add the following to your `Cargo.toml`:
```toml
[dependencies]
-mingling = "0.1.5"
+mingling = "0.1.6"
```
-> **Mingling** is an **async program**, so please use `async-std`, `tokio`, or another async runtime.
-
-2. This article assumes you are using the `tokio` async runtime. Add the following to your `Cargo.toml`:
-```toml
-tokio = {
- version = "1",
- features = [
- "macros",
- "rt",
- "rt-multi-thread"
- ]
-}
-```
-
-3. Write the basic code in your `main.rs` or other program entry point.
+2. Write the basic code in your `main.rs` or other program entry point.
```rust
use mingling::macros::{dispatcher, gen_program, r_println, renderer};
@@ -55,7 +41,7 @@ fn render_hello(_prev: HelloEntry) {
gen_program!();
```
-4. Install your command-line program and run it.
+3. Install your command-line program and run it.
```bash
cargo install --path ./
your_bin hello
@@ -65,5 +51,17 @@ Result:
Hello, World!
```
+## About Async Runtime
+
+**Mingling** supports **async runtime**, you can enable the `async` feature to activate it.
+
+After enabling it, **Mingling** will have the following changes:
+
+- The `Chain` trait and `chain!` macro will require you to use **async functions**
+- `Program::exec` will become an async function
+- The `gen_program!` macro will generate async functions
+
+**Mingling** does not depend on any specific asynchronous runtime internally, which means you can freely choose a suitable asynchronous runtime for your program (such as `async-std`, `tokio`)
+
## 💡 Next Steps
> **Mingling**'s basic components [Go](./pages/2-basic)
diff --git a/docs/pages/2-basic/1-program.md b/docs/pages/2-basic/1-program.md
index fd8e986..ae22896 100644
--- a/docs/pages/2-basic/1-program.md
+++ b/docs/pages/2-basic/1-program.md
@@ -45,12 +45,11 @@ use mingling::{
setup::BasicProgramSetup
};
-#[tokio::main]
-async fn main() {
+fn main() {
let mut program = ThisProgram::new();
// Add `BasicProgramSetup`
program.with_setup(BasicProgramSetup);
- program.exec().await;
+ program.exec();
}
// Generate `ThisProgram`
@@ -68,8 +67,7 @@ dispatcher!("member.add",
dispatcher!("member.rm",
RemoveMemberCommand => RemoveMemberEntry);
-#[tokio::main]
-async fn main() {
+fn main() {
let mut program = ThisProgram::new();
// Register Dispatchers
@@ -82,7 +80,7 @@ async fn main() {
RemoveMemberCommand
));
- program.exec().await;
+ program.exec();
}
```
@@ -91,8 +89,7 @@ async fn main() {
You can extract global arguments before the program runs to control the global state of the `Program`:
```rust
-#[tokio::main]
-async fn main() {
+fn main() {
let mut program = ThisProgram::new();
let mut output = current_dir().unwrap();
@@ -109,7 +106,7 @@ async fn main() {
|_, v| output = PathBuf::from(v)
);
- program.exec().await;
+ program.exec();
}
```
diff --git a/docs/pages/2-basic/2-setup.md b/docs/pages/2-basic/2-setup.md
index 8dbdd76..c80b91e 100644
--- a/docs/pages/2-basic/2-setup.md
+++ b/docs/pages/2-basic/2-setup.md
@@ -38,11 +38,10 @@ use mingling::{
static OUTPUT_PATH: std::sync::OnceLock<PathBuf>
= std::sync::OnceLock::new();
-#[tokio::main]
-async fn main() {
+fn main() {
let mut program = ThisProgram::new();
program.with_setup(MySetup);
- program.exec().await;
+ program.exec();
}
// Define two Dispatchers using `dispatcher!`
diff --git a/docs/pages/2-basic/3-dispatcher.md b/docs/pages/2-basic/3-dispatcher.md
index d0858d2..66e5c90 100644
--- a/docs/pages/2-basic/3-dispatcher.md
+++ b/docs/pages/2-basic/3-dispatcher.md
@@ -45,13 +45,12 @@ dispatcher!(MyProgram, "hello",
**Tips:** Finally, add the `Dispatcher` you created to the [Program](pages/2-basic/1-program):
```rust
-#[tokio::main]
-async fn main() {
+fn main() {
let mut program = ThisProgram::new();
program.with_dispatcher(HelloCommand);
program.with_dispatcher(SubFooCommand);
program.with_dispatcher(SubBarCommand);
- program.exec().await;
+ program.exec();
}
```
diff --git a/docs/pages/2-basic/4-chain.md b/docs/pages/2-basic/4-chain.md
index 87a50f2..0fd375a 100644
--- a/docs/pages/2-basic/4-chain.md
+++ b/docs/pages/2-basic/4-chain.md
@@ -19,7 +19,7 @@ pack!(ParsedHello = String);
// Define chain parse_hello (expands to ParseHello)
// Declare conversion from HelloEntry
#[chain]
-async fn parse_hello(prev: HelloEntry) -> NextProcess {
+fn parse_hello(prev: HelloEntry) -> NextProcess {
// Take the inner reference of HelloEntry
let args = &*prev;
@@ -41,10 +41,6 @@ async fn parse_hello(prev: HelloEntry) -> NextProcess {
## Manual Impl
-> ⚠️ WARNING
->
-> The following content is not yet fully implemented; currently, only the `chain!` macro is allowed for implementation.
-
You can also manually implement the basic `Chain` for finer control.
However, please note that within the `chain!` macro, a `register_type!` macro is executed. This macro does not expand to any content; it only informs the `gen_program` context that this type exists.
@@ -58,7 +54,7 @@ pack!(ParsedHello = String);
struct ParseHello;
impl Chain<ThisProgram> for ParseHello {
type Previous = HelloEntry;
- async fn proc(prev: Self::Previous)
+ fn proc(prev: Self::Previous)
-> ChainProcess<ThisProgram>
{
let args = &*prev;
@@ -72,9 +68,8 @@ impl Chain<ThisProgram> for ParseHello {
}
}
-// Register HelloEntry to the context and
-// assign an ID for it
-register_type!(HelloEntry);
+// Register chain to the context
+register_chain!(HelloEntry);
```
## 💡 Next Page
diff --git a/docs/pages/2-basic/5-renderer.md b/docs/pages/2-basic/5-renderer.md
index 1f566f2..12ac00f 100644
--- a/docs/pages/2-basic/5-renderer.md
+++ b/docs/pages/2-basic/5-renderer.md
@@ -21,7 +21,7 @@ pack!(ParsedHello = String);
// It's the Chain defined in the Dispatcher chapter
#[chain]
-async fn parse_hello(prev: HelloEntry) -> NextProcess {
+fn parse_hello(prev: HelloEntry) -> NextProcess {
let args = &*prev;
let first = args
.first()
@@ -53,10 +53,6 @@ fn render_hello(prev: ParsedHello) {
## Manual Impl
-> ⚠️ WARNING
->
-> The following content is not yet fully implemented; currently, only the `renderer!` macro is allowed for implementation.
-
Similarly, you can also manually implement `Renderer`,
but note that inside the `renderer!` macro, a `register_type!` macro is executed. This macro itself does not expand into any content; it is only used to inform the `gen_program` context that the type exists:
@@ -73,5 +69,6 @@ impl Renderer for RenderHello {
}
}
-register_type!(ParsedHello);
+// Register renderer to the context
+register_renderer!(ParsedHello);
```
diff --git a/docs/pages/3-features/1-parser.md b/docs/pages/3-features/1-parser.md
index 2ebe31c..f89091b 100644
--- a/docs/pages/3-features/1-parser.md
+++ b/docs/pages/3-features/1-parser.md
@@ -25,7 +25,7 @@ The following demonstrates the parsing approach without using a `Picker`:
```rust
#[chain]
-async fn parse_hello(prev: HelloEntry) -> NextProcess {
+fn parse_hello(prev: HelloEntry) -> NextProcess {
let args = &*prev;
let first = args.first().cloned().unwrap_or_else(|| "World".to_string());
ParsedHello::new(first).to_render()
@@ -36,7 +36,7 @@ This is how it looks when using `Picker`:
```rust
#[chain]
-async fn parse_hello(prev: HelloEntry) -> NextProcess {
+fn parse_hello(prev: HelloEntry) -> NextProcess {
// Create Picker
let picker = Picker::<ThisProgram>::new(prev.inner);
@@ -102,11 +102,10 @@ use mingling::{
parser::PickableEnum,
};
-#[tokio::main]
-async fn main() {
+fn main() {
let mut program = ThisProgram::new();
program.with_dispatcher(FruitEatCommand);
- program.exec().await;
+ program.exec();
}
dispatcher!("eat",
@@ -131,7 +130,7 @@ enum Fruit {
impl PickableEnum for Fruit {}
#[chain]
-async fn parse_fruit_eat(prev: FruitEatEntry) -> NextProcess {
+fn parse_fruit_eat(prev: FruitEatEntry) -> NextProcess {
// ...
}
@@ -197,7 +196,7 @@ Now start writing the logic:
```rust
#[chain]
-async fn parse_fruit_eat(prev: FruitEatEntry) -> NextProcess {
+fn parse_fruit_eat(prev: FruitEatEntry) -> NextProcess {
let picker = Picker::new(prev.inner);
let mut min_weight: i16 = 0;
let parsed = picker
@@ -247,11 +246,10 @@ use mingling::{
parser::{PickableEnum, Picker},
};
-#[tokio::main]
-async fn main() {
+fn main() {
let mut program = ThisProgram::new();
program.with_dispatcher(FruitEatCommand);
- program.exec().await;
+ program.exec();
}
dispatcher!("eat",
@@ -277,7 +275,7 @@ impl PickableEnum for Fruit {}
pack!(MinGreaterThanMax = ());
#[chain]
-async fn parse_fruit_eat(prev: FruitEatEntry) -> NextProcess {
+fn parse_fruit_eat(prev: FruitEatEntry) -> NextProcess {
let picker = Picker::new(prev.inner);
let mut min_weight: i16 = 0;
let parsed = picker
diff --git a/docs/res/guide.txt b/docs/res/guide.txt
index 4de56b3..89c6d8b 100644
--- a/docs/res/guide.txt
+++ b/docs/res/guide.txt
@@ -7,6 +7,6 @@
│ > cargo add mingling │
│ │
│ Or add this to your Cargo.toml │
- │ > mingling = "0.1.5" │
+ │ > mingling = "0.1.6" │
│ │
└────────────────────────────────────┘
diff --git a/mingling/src/example_docs.rs b/mingling/src/example_docs.rs
index 8ad2bb2..31a298f 100644
--- a/mingling/src/example_docs.rs
+++ b/mingling/src/example_docs.rs
@@ -16,7 +16,6 @@
///
/// [dependencies]
/// mingling = { path = "../../mingling" }
-/// tokio = { version = "1", features = ["rt", "rt-multi-thread", "macros"] }
/// ```
///
/// main.rs
@@ -29,8 +28,7 @@
/// // Define dispatcher `HelloCommand`, directing subcommand "hello" to `HelloEntry`
/// dispatcher!("hello", HelloCommand => HelloEntry);
///
-/// #[tokio::main]
-/// async fn main() {
+/// fn main() {
/// // Create program
/// let mut program = ThisProgram::new();
///
@@ -38,7 +36,7 @@
/// program.with_dispatcher(HelloCommand);
///
/// // Run program
-/// program.exec().await;
+/// program.exec();
/// }
///
/// // Register wrapper type `Hello`, setting inner to `String`
@@ -46,7 +44,7 @@
///
/// // Register chain to `ThisProgram`, handling logic from `HelloEntry`
/// #[chain]
-/// async fn parse_name(prev: HelloEntry) -> NextProcess {
+/// fn parse_name(prev: HelloEntry) -> NextProcess {
/// // Extract string from `HelloEntry` as argument
/// let name = prev.first().cloned().unwrap_or_else(|| "World".to_string());
///
@@ -102,7 +100,6 @@ pub mod example_basic {}
///
/// [dependencies]
/// mingling = { path = "../../mingling", features = ["comp", "parser"] }
-/// tokio = { version = "1", features = ["rt", "rt-multi-thread", "macros"] }
/// ```
///
/// main.rs
@@ -137,12 +134,11 @@ pub mod example_basic {}
/// return suggest!();
/// }
///
-/// #[tokio::main]
-/// async fn main() {
+/// fn main() {
/// let mut program = ThisProgram::new();
/// program.with_dispatcher(CompletionDispatcher);
/// program.with_dispatcher(FruitCommand);
-/// program.exec().await;
+/// program.exec();
/// }
///
/// #[derive(Groupped)]
@@ -181,7 +177,7 @@ pub mod example_basic {}
/// impl PickableEnum for FruitType {}
///
/// #[chain]
-/// async fn parse_fruit_info(prev: FruitEntry) -> NextProcess {
+/// fn parse_fruit_info(prev: FruitEntry) -> NextProcess {
/// let picker = Picker::<()>::from(prev.inner);
/// let (fruit_name, fruit_type) = picker.pick("--name").pick("--type").unpack_directly();
/// let info = FruitInfo {
@@ -259,7 +255,6 @@ pub mod example_completion {}
/// "general_renderer",
/// ] }
/// serde = { version = "1", features = ["derive"] }
-/// tokio = { version = "1", features = ["rt", "rt-multi-thread", "macros"] }
/// ```
///
/// main.rs
@@ -275,13 +270,12 @@ pub mod example_completion {}
///
/// dispatcher!("render", RenderCommand => RenderCommandEntry);
///
-/// #[tokio::main]
-/// async fn main() {
+/// fn main() {
/// let mut program = ThisProgram::new();
/// // Add `GeneralRendererSetup` to receive user input `--json` `--yaml` parameters
/// program.with_setup(GeneralRendererSetup);
/// program.with_dispatcher(RenderCommand);
-/// program.exec().await;
+/// program.exec();
/// }
///
/// // Manually implement Info struct
@@ -294,7 +288,7 @@ pub mod example_completion {}
/// }
///
/// #[chain]
-/// async fn parse_render(prev: RenderCommandEntry) -> NextProcess {
+/// fn parse_render(prev: RenderCommandEntry) -> NextProcess {
/// let (name, age) = Picker::<()>::new(prev.inner)
/// .pick::<String>(())
/// .pick::<i32>(())
@@ -352,18 +346,17 @@ pub mod example_general_renderer {}
///
/// dispatcher!("pick", PickCommand => PickEntry);
///
-/// #[tokio::main]
-/// async fn main() {
+/// fn main() {
/// let mut program = ThisProgram::new();
/// program.with_dispatcher(PickCommand);
-/// program.exec().await;
+/// program.exec();
/// }
///
/// pack!(NoNameProvided = ());
/// pack!(ParsedPickInput = (i32, String));
///
/// #[chain]
-/// async fn parse(prev: PickEntry) -> NextProcess {
+/// fn parse(prev: PickEntry) -> NextProcess {
/// // Extract arguments from `PickEntry`'s inner and create a `Picker`
/// let picker = Picker::new(prev.inner);
/// let picked = picker