aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md54
-rw-r--r--GETTING-STARTED.md12
-rw-r--r--arg_picker/src/arg.rs18
-rw-r--r--docs/_zh_CN/pages/14-testing.md4
-rw-r--r--docs/_zh_CN/pages/2-define-a-dispatcher.md4
-rw-r--r--docs/_zh_CN/pages/6-argument-parse-picker.md10
-rw-r--r--docs/_zh_CN/pages/8-setup-and-resources.md6
-rw-r--r--docs/_zh_CN/pages/9-error-handling.md4
-rw-r--r--docs/_zh_CN/pages/other/features.md12
-rw-r--r--docs/dev/pages/issues/_the-mod-pathfinder.md2
-rw-r--r--docs/dev/pages/issues/the-command-macro.md6
-rw-r--r--docs/example-pages/examples.json12
-rw-r--r--docs/pages/14-testing.md4
-rw-r--r--docs/pages/2-define-a-dispatcher.md4
-rw-r--r--docs/pages/6-argument-parse-picker.md10
-rw-r--r--docs/pages/8-setup-and-resources.md6
-rw-r--r--docs/pages/9-error-handling.md4
-rw-r--r--docs/pages/other/features.md12
-rw-r--r--examples/example-argument-parse/Cargo.toml2
-rw-r--r--examples/example-argument-picker/Cargo.toml2
-rw-r--r--examples/example-combine-pathf-dispatch-tree/Cargo.toml2
-rw-r--r--examples/example-combine-pathf-dispatch-tree/page.toml2
-rw-r--r--examples/example-combine-pathf-dispatch-tree/src/main.rs2
-rw-r--r--examples/example-command-macro/Cargo.toml4
-rw-r--r--examples/example-custom-pickable/Cargo.toml2
-rw-r--r--examples/example-implicit-dispatcher/Cargo.toml2
-rw-r--r--examples/example-implicit-dispatcher/page.toml2
-rw-r--r--examples/example-implicit-dispatcher/src/main.rs2
-rw-r--r--examples/example-outside-type/Cargo.toml2
-rw-r--r--examples/example-outside-type/page.toml2
-rw-r--r--examples/example-pack-err/Cargo.toml2
-rw-r--r--examples/example-pack-err/page.toml2
-rw-r--r--examples/example-repl-basic/Cargo.toml2
-rw-r--r--examples/example-setup/Cargo.toml2
-rw-r--r--examples/example-setup/page.toml2
-rw-r--r--examples/example-unit-test/Cargo.toml2
-rw-r--r--examples/example-unit-test/page.toml2
-rw-r--r--examples/full-todolist/Cargo.toml2
-rw-r--r--mingling/Cargo.toml8
-rw-r--r--mingling/src/example_docs.rs28
-rw-r--r--mingling/src/features.rs11
-rw-r--r--mingling/src/lib.rs36
-rw-r--r--mingling/src/picker_comp.rs52
-rw-r--r--mingling_cli/Cargo.toml2
-rw-r--r--mingling_core/src/comp/suggest.rs36
-rw-r--r--mingling_core/src/program/collection.rs2
-rw-r--r--mingling_core/tests/test-all/Cargo.toml2
-rw-r--r--mingling_core/tests/test-repl/Cargo.toml2
-rw-r--r--mingling_macros/Cargo.toml2
-rw-r--r--mingling_macros/src/attr.rs4
-rw-r--r--mingling_macros/src/extensions.rs4
-rw-r--r--mingling_macros/src/func.rs16
-rw-r--r--mingling_macros/src/func/dispatcher.rs10
-rw-r--r--mingling_macros/src/func/suggest.rs43
-rw-r--r--mingling_macros/src/lib.rs50
55 files changed, 291 insertions, 243 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1cf0c80..514d186 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,6 +11,7 @@ Any contributor making changes to the project must record their changes in this
**- Milestone.1 "MVP" -**
- [Unreleased](#unreleased)
+- [Release 0.4.0 (Unreleased)](#release-040-unreleased)
- [Release 0.3.0 (2026-07-27)](#release-030-2026-07-27)
- [Release 0.2.2 (2026-07-10)](#release-022-2026-07-10)
- [Release 0.2.1 (2026-07-01)](#release-021-2026-07-01)
@@ -52,7 +53,7 @@ None
## Contents
-### ?.?.? (Unreleased)
+### 0.4.0 (Unreleased)
#### Fixes:
@@ -71,6 +72,13 @@ None
_No behavioral change for downstream code — all public items are re-exported with the same names. The `__this_program_impl` module is `#[doc(hidden)]` and not part of the public API._
+3. **[`core:comp`]** Added `add_suggest()` and `add_suggest_with_description()` methods to `Suggest` for batch-adding suggestion items:
+
+ - **`add_suggest(&mut self, items: impl Into<Vec<String>>)`** — Wraps each item in `SuggestItem::Simple` and inserts it into the underlying `BTreeSet`.
+ - **`add_suggest_with_description(&mut self, items: impl Into<Vec<String>>, desc: impl Into<String>)`** — Wraps each item in `SuggestItem::WithDescription` using the provided description and inserts it into the set.
+
+ These methods enable ergonomic batch population of suggestion sets from collections of strings, complementing the existing `insert()` method.
+
#### Features:
1. **[`picker:value:paths`]** Added new path wrapper types to `arg_picker::value` for filesystem-aware argument parsing:
@@ -96,7 +104,7 @@ None
These methods provide ergonomic alternatives to `to_result()` + `unwrap()` / `unwrap_or_default()` / `unwrap_or_else()` / `expect()` chaining, reducing boilerplate when working with `PickArgParsed` tuples directly.
-3. **[`macros:command`]** Added the `#[command]` attribute macro (feature-gated behind `extra_macros`) that converts a plain function with a `Vec<String>` parameter into a fully wired Mingling command. The macro:
+3. **[`macros:command`]** Added the `#[command]` attribute macro (feature-gated behind `extras`) that converts a plain function with a `Vec<String>` parameter into a fully wired Mingling command. The macro:
- Calls `dispatcher!("command_name")` to register the dispatcher entry.
- Generates a `#[chain]` wrapper that bridges the entry type (`Entry{Pascal}`) to the original function.
@@ -142,17 +150,29 @@ None
7. **[`core`]** **[`comp`]** Added `Suggest::combine(self, other: impl Into<Suggest>) -> Self` method that merges two `Suggest` values. If both are `Suggest::Suggest`, their inner `BTreeSet`s are merged (all items from `other` are added into `self`). Otherwise, the first `Suggest::Suggest` (or `FileCompletion`) is returned unchanged, and the other value is discarded. This enables ergonomic aggregation of completion suggestions from multiple sources.
-8. **[`picker_comp`]** Added `mingling::picker_comp` module behind `cfg(all(feature = "picker", feature = "comp"))` with a `PickerArgSuggest` trait and its implementation for `&PickerArg<'a, T>`. The trait provides:
-
- - **`into_suggest(self)`** — Converts the picker argument's known flags into a `Suggest` collection of `SuggestItem::Simple` entries.
- - **`into_suggest_with_desc(self, description)`** — Same as `into_suggest` but wraps each flag in `SuggestItem::WithDescription`.
- - **`into_suggest_raw(self, description: Option<&String>)`** — The core method; builds the list of possible flags from `arg_picker::parselib::build_possible_flags` and inserts each into the `Suggest` set, optionally carrying a description.
+#### **BREAKING CHANGES** (API CHANGES):
- This bridges the `picker` and `comp` (completion) subsystems, allowing picker arguments to be reused as completion candidates.
+1. **[`macros`]** **[BREAKING]** Renamed the `extra_macros` feature to `extras`. All feature-gated macro re-exports in `mingling/src/lib.rs` (and throughout the codebase) have been updated from `#[cfg(feature = "extra_macros")]` to `#[cfg(feature = "extras")]`.
+
+ **Affected macros** (all previously gated behind `extra_macros`, now `extras`):
+ - `#[command]`
+ - `empty_result!`
+ - `entry!`
+ - `group!`
+ - `group_structural!` (also requires `structural_renderer`)
+ - `pack_err!`
+ - `pack_err_structural!` (also requires `structural_renderer`)
+ - `#[program_setup]`
+ - `render_route!`
+ - `#[renderify]`
+ - `route!`
+ - `#[routeify]`
-#### **BREAKING CHANGES** (API CHANGES):
+ **Migration guide:**
+ - Update `Cargo.toml` feature declarations from `extra_macros` to `extras`.
+ - If your code references `mingling::feature::MINGLING_EXTRA_MACROS`, update it to `mingling::feature::MINGLING_EXTRAS`.
-None
+ _No behavioral changes — this is a pure feature rename. The `extras` feature provides identical functionality to the old `extra_macros` feature; all prelude and macros module re-exports remain the same under the new feature name._
---
@@ -480,7 +500,7 @@ None
}
```
- The `#[routeify]` macro is feature-gated behind `extra_macros` and re-exported as `mingling::macros::routeify`.
+ The `#[routeify]` macro is feature-gated behind `extras` and re-exported as `mingling::macros::routeify`.
Internal changes:
- Added `mingling_macros/src/extensions/routeify.rs` with `routeify_impl` implementation.
@@ -548,7 +568,7 @@ None
When used as a renderer/help extension, the `renderify` identifier is detected by the extension point mechanism, stripped from the attribute arguments, and `#[renderify]` is applied as an outer attribute on top of `#[renderer]`/`#[help]` — just like `routeify` works with `#[chain]`.
- Both `render_route!` and `#[renderify]` are feature-gated behind `extra_macros` and re-exported as `mingling::macros::render_route` and `mingling::macros::renderify` respectively.
+ Both `render_route!` and `#[renderify]` are feature-gated behind `extras` and re-exported as `mingling::macros::render_route` and `mingling::macros::renderify` respectively.
Internal changes:
- Added `mingling_macros/src/extensions/renderify.rs` with `renderify_impl` implementation.
@@ -565,7 +585,7 @@ None
fn some_item() {}
```
- Since the attribute is a no-op at compile time, it has no effect on code generation, type checking, or runtime behavior. Its purpose is to serve as a structured annotation that `mlint` tooling can parse from the AST. The attribute is feature-gated behind `extra_macros`.
+ Since the attribute is a no-op at compile time, it has no effect on code generation, type checking, or runtime behavior. Its purpose is to serve as a structured annotation that `mlint` tooling can parse from the AST. The attribute is feature-gated behind `extras`.
16. **[`core`]** Added `RendererInvoker<T, C>` and `ChainInvoker<T, C>` types to `mingling_core::asset::core_invokes`, providing a mechanism for selectively invoking renderer and chain pipelines for specific types from within chain/renderer functions via resource injection.
@@ -878,7 +898,7 @@ None
- `test-basic`: Basic type tests with default features (Node, Flag, RenderResult, NextProcess, StringVec)
- `test-comp`: ShellContext, Suggest, SuggestItem, is_completing with `comp + builds` features
- `test-structural-renderer`: StructuralRenderer output in various formats with `structural_renderer_full + parser` features
- - `test-repl`: ResREPL and basic types with `repl + extra_macros` features
+ - `test-repl`: ResREPL and basic types with `repl + extras` features
- `test-dispatch-tree`: Basic types with `dispatch_tree` feature
- `test-all`: Comprehensive testing with all feature combinations (ShellContext, Suggest, ResREPL, StructuralRenderer, Hooks, basic types, etc.)
@@ -1042,7 +1062,7 @@ impl ErrorNotDir {
}
```
-This macro is only available with the `extra_macros` feature.
+This macro is only available with the `extras` feature.
9. **[`mingling`]** Added `Groupped` trait to the `mingling::prelude` module, so it can now be imported via `use mingling::prelude::*` without needing to separately import the trait from the `mingling` crate root.
@@ -1061,7 +1081,7 @@ An aliased syntax is also supported for descriptive variant naming:
group!(IoError = std::io::Error);
```
-This macro is only available with the `extra_macros` feature.
+This macro is only available with the `extras` feature.
11. **[`macros`]** `#[help]` and `#[completion]` now support resource injection parameters, consistent with `#[chain]` and `#[renderer]`. Specific changes:
@@ -1452,7 +1472,7 @@ fn render(prev: Previous) { // Implicitly introduces `__renderer_inner_result`
}
```
-5. **[`macros`]** Moved the `entry!`, `route!`, `#[program_setup]` macros into the `extra_macros` feature
+5. **[`macros`]** Moved the `entry!`, `route!`, `#[program_setup]` macros into the `extras` feature
6. **[`macros`]** The `crate::Next` generated by `gen_program!()` now requires explicit import into the project
diff --git a/GETTING-STARTED.md b/GETTING-STARTED.md
index 516122e..7d451e0 100644
--- a/GETTING-STARTED.md
+++ b/GETTING-STARTED.md
@@ -49,10 +49,10 @@ fn main() {
}
```
-Mingling also supports an abbreviated form (with the `extra_macros` feature):
+Mingling also supports an abbreviated form (with the `extras` feature):
```rust
-// Features: ["extra_macros"]
+// Features: ["extras"]
// Auto-generates CMDGreet / EntryGreet from "greet"
dispatcher!("greet");
@@ -192,7 +192,7 @@ The flow is:
With the `comp` feature, Mingling provides a fully dynamic completion system. You write a function that returns `Suggest` based on the current shell context, and Mingling generates the completion scripts for bash, zsh, fish, and pwsh.
```rust
-// Features: ["comp", "extra_macros"]
+// Features: ["comp", "extras"]
use mingling::{macros::suggest, ShellContext, Suggest};
@@ -246,7 +246,7 @@ mingling::build::build_comp_scripts(env!("CARGO_PKG_NAME")).unwrap();
For enum-based completions, use `suggest_enum!`:
```rust
-// Features: ["comp", "extra_macros"]
+// Features: ["comp", "extras"]
use mingling::{ShellContext, Suggest};
use mingling::macros::suggest_enum;
@@ -323,7 +323,7 @@ Two built-in fallback types are always available:
Chain and renderer functions can accept **additional parameters** for the program's global state. Resources are singleton values registered with `program.with_resource(...)`.
```rust
-// Features: ["picker", "extra_macros"]
+// Features: ["picker", "extras"]
use std::path::PathBuf;
@@ -492,7 +492,7 @@ fn main() {
Mingling provides built-in REPL setups:
```rust
-// Features: ["repl", "extra_macros"]
+// Features: ["repl", "extras"]
use mingling::{
res::ResREPL,
diff --git a/arg_picker/src/arg.rs b/arg_picker/src/arg.rs
index 4fa21b5..0b5176d 100644
--- a/arg_picker/src/arg.rs
+++ b/arg_picker/src/arg.rs
@@ -1,4 +1,4 @@
-use crate::{Pickable, PickerArgInfo};
+use crate::{Pickable, PickerArgInfo, SinglePickable, parselib::ParserStyle};
use std::marker::PhantomData;
/// Represents a constraint definition for a parameter selection.
@@ -164,6 +164,22 @@ where
}
}
+impl<'a, Type> From<PickerArg<'a, Type>> for Vec<String>
+where
+ Type: SinglePickable,
+{
+ fn from(value: PickerArg<'a, Type>) -> Self {
+ let mut result = Vec::new();
+ let info = PickerArgInfo::from(value);
+ let possible_flags =
+ crate::parselib::build_possible_flags(ParserStyle::global_style(), &info);
+ for flag in possible_flags {
+ result.push(flag);
+ }
+ result
+ }
+}
+
/// Describes the attribute (behavior) of a command-line parameter.
///
/// The ordering reflects parse priority (higher = parsed first):
diff --git a/docs/_zh_CN/pages/14-testing.md b/docs/_zh_CN/pages/14-testing.md
index 031be59..3567aef 100644
--- a/docs/_zh_CN/pages/14-testing.md
+++ b/docs/_zh_CN/pages/14-testing.md
@@ -70,10 +70,10 @@ fn test_handle_hello_with_name() {
## 用 entry! 宏构造数据
-如果启用了 `extra_macros`,可以用 `entry!` 快速构造 Entry:
+如果启用了 `extras`,可以用 `entry!` 快速构造 Entry:
```rust
-// Features: ["extra_macros"]
+// Features: ["extras"]
@@@use mingling::{assert_member_id, unpack_chain_process};
@@@use mingling::macros::entry;
diff --git a/docs/_zh_CN/pages/2-define-a-dispatcher.md b/docs/_zh_CN/pages/2-define-a-dispatcher.md
index 0afd911..b238d9f 100644
--- a/docs/_zh_CN/pages/2-define-a-dispatcher.md
+++ b/docs/_zh_CN/pages/2-define-a-dispatcher.md
@@ -79,10 +79,10 @@ pub struct EntryGreet {
## 进阶:隐式声明
-以上是标准写法。如果你启用了 `extra_macros` 特性,还可以更简洁:
+以上是标准写法。如果你启用了 `extras` 特性,还可以更简洁:
```rust
-// Features: ["extra_macros"]
+// Features: ["extras"]
// 省略 CMDType 和 EntryType,名字自动推导
dispatcher!("greet");
// dispatcher!("greet", CMDGreet => EntryGreet);
diff --git a/docs/_zh_CN/pages/6-argument-parse-picker.md b/docs/_zh_CN/pages/6-argument-parse-picker.md
index f0609ed..462a912 100644
--- a/docs/_zh_CN/pages/6-argument-parse-picker.md
+++ b/docs/_zh_CN/pages/6-argument-parse-picker.md
@@ -138,7 +138,7 @@ fn handle_test_entry(prev: EntryTest) -> Next {
先来看一个简单示例
```rust
-// Features: ["parser", "extra_macros"]
+// Features: ["parser", "extras"]
@@@use mingling::macros::buffer;
@@@use mingling::macros::route;
@@@dispatcher!("greet", CMDGreet => EntryGreet);
@@ -164,10 +164,10 @@ fn render_greet(result: ResultName) {
若使用 `pick_or_route`,写法会变得相对复杂:因为 `.unpack()` 不再直接返回参数,而是 `Result<Value, Route>`。
-不过 **Mingling** 的 `extra_macros` 特性提供了简化展开的宏 `route!`,它不复杂,只是省略了一部分样板代码:
+不过 **Mingling** 的 `extras` 特性提供了简化展开的宏 `route!`,它不复杂,只是省略了一部分样板代码:
```rust
-// Features: ["parser", "extra_macros"]
+// Features: ["parser", "extras"]
@@@ pack!(ErrorFail = ());
@@@ use mingling::macros::route;
@@@ fn func() -> mingling::ChainProcess<ThisProgram> {
@@ -181,7 +181,7 @@ let name = route!(pick_result);
它展开为:
```rust
-// Features: ["parser", "extra_macros"]
+// Features: ["parser", "extras"]
@@@ pack!(ErrorFail = ());
@@@ fn func() -> mingling::ChainProcess<ThisProgram> {
@@@ let args: Vec<String> = vec![];
@@ -223,7 +223,7 @@ fn handle_greet_entry(prev: EntryGreet) -> Next {
同样,你可以使用 `after_or_route` 来处理输入参数的格式错误
```rust
-// Features: ["parser", "extra_macros"]
+// Features: ["parser", "extras"]
@@@use mingling::macros::buffer;
@@@use mingling::macros::route;
@@@dispatcher!("greet", CMDGreet => EntryGreet);
diff --git a/docs/_zh_CN/pages/8-setup-and-resources.md b/docs/_zh_CN/pages/8-setup-and-resources.md
index d38e69d..9ed9894 100644
--- a/docs/_zh_CN/pages/8-setup-and-resources.md
+++ b/docs/_zh_CN/pages/8-setup-and-resources.md
@@ -8,7 +8,7 @@
## 用 Setup 做初始化
```rust
-// Features: ["extra_macros"]
+// Features: ["extras"]
@@@use mingling::macros::program_setup;
@@@use mingling::Program;
#[program_setup]
@@ -32,14 +32,14 @@ fn my_setup(program: &mut Program<ThisProgram>) {
在 `main` 里通过 `program.with_setup(...)` 注册即可使用。
> [!NOTE]
-> `#[program_setup]` 需要 `extra_macros` 特性。没有此特性时,可以手动实现 `ProgramSetup` trait。
+> `#[program_setup]` 需要 `extras` 特性。没有此特性时,可以手动实现 `ProgramSetup` trait。
## 提取全局参数
Setup 里最常用的操作就是提取全局参数。Mingling 提供了几个辅助方法:
```rust
-// Features: ["extra_macros"]
+// Features: ["extras"]
@@@use mingling::macros::program_setup;
@@@use mingling::Program;
#[program_setup]
diff --git a/docs/_zh_CN/pages/9-error-handling.md b/docs/_zh_CN/pages/9-error-handling.md
index 4ce61ab..f5055b8 100644
--- a/docs/_zh_CN/pages/9-error-handling.md
+++ b/docs/_zh_CN/pages/9-error-handling.md
@@ -107,10 +107,10 @@ Error: name is required
## 关于 `pack_err!`
-如果你启用了 `extra_macros`,还可以用 `pack_err!` 快速声明带有自动 `name` 字段的错误类型:
+如果你启用了 `extras`,还可以用 `pack_err!` 快速声明带有自动 `name` 字段的错误类型:
```rust
-// Features: ["extra_macros"]
+// Features: ["extras"]
pack_err!(ErrorNotFound);
// 生成: struct ErrorNotFound { pub name: String }
```
diff --git a/docs/_zh_CN/pages/other/features.md b/docs/_zh_CN/pages/other/features.md
index 8bd386c..84010c4 100644
--- a/docs/_zh_CN/pages/other/features.md
+++ b/docs/_zh_CN/pages/other/features.md
@@ -83,7 +83,7 @@ build_comp_scripts("myprogram").unwrap();
详见 [示例](https://mingling-rs.github.io/mingling/docs/example-viewer.html?name=example-dispatch-tree)
-## 特性 `extra_macros`
+## 特性 `extras`
**介绍:**
@@ -106,7 +106,7 @@ build_comp_scripts("myprogram").unwrap();
### `empty_result!()`
```rust
-// Features: ["extra_macros"]
+// Features: ["extras"]
pack!(StatePrev1 = ());
pack!(StatePrev2 = ());
@@ -134,7 +134,7 @@ fn handle_state_prev1(_p: StatePrev1) -> Next {
### `#[program_setup]`
```rust
-// Features: ["extra_macros"]
+// Features: ["extras"]
use mingling::{macros::program_setup, Program};
fn main() {
@@ -154,7 +154,7 @@ fn no_error_setup(program: &mut Program<ThisProgram>) {
### `entry!`
```rust
-// Features: ["extra_macros"]
+// Features: ["extras"]
use mingling::macros::entry;
pack!(EntryHello = Vec<String>);
@@ -174,7 +174,7 @@ fn handle_hello(args: EntryHello) {}
类型名会直接作为枚举变体,与 `pack!` 或 `#[derive(Grouped)]` 一致。
```rust
-// Features: ["extra_macros"]
+// Features: ["extras"]
use mingling::macros::group;
use std::num::ParseIntError;
@@ -189,7 +189,7 @@ group!(std::num::ParseIntError);
可选择包裹一个内部类型以携带额外上下文。
```rust
-// Features: ["extra_macros"]
+// Features: ["extras"]
use std::path::PathBuf;
// 简单形式——仅包含 name 字段:
diff --git a/docs/dev/pages/issues/_the-mod-pathfinder.md b/docs/dev/pages/issues/_the-mod-pathfinder.md
index 8869beb..92cdb5f 100644
--- a/docs/dev/pages/issues/_the-mod-pathfinder.md
+++ b/docs/dev/pages/issues/_the-mod-pathfinder.md
@@ -32,7 +32,7 @@ mod sub {
}
```
-There are a few exceptions, such as the implicit Dispatcher provided by `extra_macros`, but these can be inferred from the node name:
+There are a few exceptions, such as the implicit Dispatcher provided by `extras`, but these can be inferred from the node name:
```rust
dispatcher!("remote.add"); // although the type is unknown, we can infer CMDRemoteAdd and EntryRemoteAdd
diff --git a/docs/dev/pages/issues/the-command-macro.md b/docs/dev/pages/issues/the-command-macro.md
index 2f4a80a..82d733c 100644
--- a/docs/dev/pages/issues/the-command-macro.md
+++ b/docs/dev/pages/issues/the-command-macro.md
@@ -16,7 +16,7 @@ For a long time, creating a command in Mingling required the following steps:
dispatcher!("greet", CMDGreet => EntryGreet);
```
-Or use the implicit syntax provided by `extra_macros` (automatically deriving `CMDGreet` and `EntryGreet`):
+Or use the implicit syntax provided by `extras` (automatically deriving `CMDGreet` and `EntryGreet`):
```rust
dispatcher!("greet");
@@ -151,11 +151,11 @@ In Mingling, there is no concept called `Command` — all behavior is the result
## Enabling
-This macro requires the `extra_macros` feature. Enable it in your `Cargo.toml`:
+This macro requires the `extras` feature. Enable it in your `Cargo.toml`:
```toml
[dependencies]
-mingling = { version = "...", features = ["extra_macros"] }
+mingling = { version = "...", features = ["extras"] }
```
## Caveats
diff --git a/docs/example-pages/examples.json b/docs/example-pages/examples.json
index 349248e..bde9d35 100644
--- a/docs/example-pages/examples.json
+++ b/docs/example-pages/examples.json
@@ -84,7 +84,7 @@
"tags": [
"pathf",
"dispatch_tree",
- "extra_macros",
+ "extras",
"build.rs"
],
"files": [
@@ -230,7 +230,7 @@
"name": "Implicit Dispatcher",
"icon": "🫥",
"category": "dispatch",
- "desc": "Shows the abbreviated `dispatcher!(\"cmd.path\")` syntax from `extra_macros` that auto-derives struct names from the command path.\n",
+ "desc": "Shows the abbreviated `dispatcher!(\"cmd.path\")` syntax from `extras` that auto-derives struct names from the command path.\n",
"tags": [
"implicit"
],
@@ -261,7 +261,7 @@
"desc": "Demonstrates how to use the `group!()` macro to convert an external type into a type recognizable by Mingling\n",
"tags": [
"group!",
- "extra_macros"
+ "extras"
],
"files": [
"src/main.rs",
@@ -276,7 +276,7 @@
"desc": "Demonstrates how to use the `pack_err!` macro to define error types with automatic `name` field (snake_case at compile time) and optional `info` field. Also shows `--json` serialization when `structural_renderer` is enabled.\n",
"tags": [
"pack_err!",
- "extra_macros",
+ "extras",
"structural_renderer",
"--json"
],
@@ -354,7 +354,7 @@
"desc": "Demonstrates how to build a custom `ProgramSetup` with `#[program_setup]` for modular configuration of program behaviour.\n",
"tags": [
"#[setup]",
- "extra_macros"
+ "extras"
],
"files": [
"src/main.rs",
@@ -385,7 +385,7 @@
"desc": "Shows how to write unit tests for Chain and Renderer functions using the `entry!` macro and assertion helpers.\n",
"tags": [
"testing",
- "extra_macros"
+ "extras"
],
"files": [
"src/main.rs",
diff --git a/docs/pages/14-testing.md b/docs/pages/14-testing.md
index 65fedc9..86171bf 100644
--- a/docs/pages/14-testing.md
+++ b/docs/pages/14-testing.md
@@ -70,10 +70,10 @@ What the three test macros do:
## Constructing Data with the entry! Macro
-If `extra_macros` is enabled, you can use `entry!` to quickly construct an Entry:
+If `extras` is enabled, you can use `entry!` to quickly construct an Entry:
```rust
-// Features: ["extra_macros"]
+// Features: ["extras"]
@@@use mingling::{assert_member_id, unpack_chain_process};
@@@use mingling::macros::entry;
diff --git a/docs/pages/2-define-a-dispatcher.md b/docs/pages/2-define-a-dispatcher.md
index 804ad1b..1208e64 100644
--- a/docs/pages/2-define-a-dispatcher.md
+++ b/docs/pages/2-define-a-dispatcher.md
@@ -79,10 +79,10 @@ When the user types `greet Alice Bob` on the command line, `EntryGreet.inner` be
## Advanced: Implicit Declaration
-The above is the standard syntax. If you enable the `extra_macros` feature, you can be more concise:
+The above is the standard syntax. If you enable the `extras` feature, you can be more concise:
```rust
-// Features: ["extra_macros"]
+// Features: ["extras"]
// Omit CMDType and EntryType, names are auto-derived
dispatcher!("greet");
// dispatcher!("greet", CMDGreet => EntryGreet);
diff --git a/docs/pages/6-argument-parse-picker.md b/docs/pages/6-argument-parse-picker.md
index 01f1c37..d7d38af 100644
--- a/docs/pages/6-argument-parse-picker.md
+++ b/docs/pages/6-argument-parse-picker.md
@@ -138,7 +138,7 @@ As the saying goes: "never trust your users." To handle missing required params,
Here's a simple example:
```rust
-// Features: ["parser", "extra_macros"]
+// Features: ["parser", "extras"]
@@@use mingling::macros::buffer;
@@@use mingling::macros::route;
@@@dispatcher!("greet", CMDGreet => EntryGreet);
@@ -164,10 +164,10 @@ fn render_greet(result: ResultName) {
With `pick_or_route`, the code becomes more involved: `.unpack()` no longer returns the value directly, but `Result<Value, Route>`.
-However, **Mingling**'s `extra_macros` feature provides the `route!` macro for simplified expansion. It's not complex — it just reduces boilerplate:
+However, **Mingling**'s `extras` feature provides the `route!` macro for simplified expansion. It's not complex — it just reduces boilerplate:
```rust
-// Features: ["parser", "extra_macros"]
+// Features: ["parser", "extras"]
@@@ pack!(ErrorFail = ());
@@@ use mingling::macros::route;
@@@ fn func() -> mingling::ChainProcess<ThisProgram> {
@@ -181,7 +181,7 @@ let name = route!(pick_result);
It expands to:
```rust
-// Features: ["parser", "extra_macros"]
+// Features: ["parser", "extras"]
@@@ pack!(ErrorFail = ());
@@@ fn func() -> mingling::ChainProcess<ThisProgram> {
@@@ let args: Vec<String> = vec![];
@@ -223,7 +223,7 @@ fn handle_greet_entry(prev: EntryGreet) -> Next {
Similarly, you can use `after_or_route` to handle input format errors:
```rust
-// Features: ["parser", "extra_macros"]
+// Features: ["parser", "extras"]
@@@use mingling::macros::buffer;
@@@use mingling::macros::route;
@@@dispatcher!("greet", CMDGreet => EntryGreet);
diff --git a/docs/pages/8-setup-and-resources.md b/docs/pages/8-setup-and-resources.md
index 3858e99..12c7610 100644
--- a/docs/pages/8-setup-and-resources.md
+++ b/docs/pages/8-setup-and-resources.md
@@ -8,7 +8,7 @@ When a program needs to do some init work at startup—like parsing global args
## Initialize with Setup
```rust
-// Features: ["extra_macros"]
+// Features: ["extras"]
@@@use mingling::macros::program_setup;
@@@use mingling::Program;
#[program_setup]
@@ -32,14 +32,14 @@ A function annotated with `#[program_setup]` receives `&mut Program<ThisProgram>
Register it in `main` via `program.with_setup(...)` to use it.
> [!NOTE]
-> `#[program_setup]` requires the `extra_macros` feature. Without it, you can manually implement the `ProgramSetup` trait.
+> `#[program_setup]` requires the `extras` feature. Without it, you can manually implement the `ProgramSetup` trait.
## Extract Global Args
The most common use of Setup is extracting global args. Mingling provides a few helper methods:
```rust
-// Features: ["extra_macros"]
+// Features: ["extras"]
@@@use mingling::macros::program_setup;
@@@use mingling::Program;
#[program_setup]
diff --git a/docs/pages/9-error-handling.md b/docs/pages/9-error-handling.md
index f6e05e3..680328c 100644
--- a/docs/pages/9-error-handling.md
+++ b/docs/pages/9-error-handling.md
@@ -107,10 +107,10 @@ Error: name is required
## About `pack_err!`
-If you've enabled `extra_macros`, you can use `pack_err!` to quickly declare an error type with an auto-generated `name` field:
+If you've enabled `extras`, you can use `pack_err!` to quickly declare an error type with an auto-generated `name` field:
```rust
-// Features: ["extra_macros"]
+// Features: ["extras"]
pack_err!(ErrorNotFound);
// Generates: struct ErrorNotFound { pub name: String }
```
diff --git a/docs/pages/other/features.md b/docs/pages/other/features.md
index 7994d4c..465c290 100644
--- a/docs/pages/other/features.md
+++ b/docs/pages/other/features.md
@@ -83,7 +83,7 @@ When enabled, Mingling **at compile time** hard-codes the subcommand structure a
See [example](https://mingling-rs.github.io/mingling/docs/example-viewer.html?name=example-dispatch-tree)
-## Feature `extra_macros`
+## Feature `extras`
**Description:**
@@ -106,7 +106,7 @@ For example, allows the shorthand form `dispatcher!("greet")`, which auto-genera
### `empty_result!()`
```rust
-// Features: ["extra_macros"]
+// Features: ["extras"]
pack!(StatePrev1 = ());
pack!(StatePrev2 = ());
@@ -134,7 +134,7 @@ fn handle_state_prev1(_p: StatePrev1) -> Next {
### `#[program_setup]`
```rust
-// Features: ["extra_macros"]
+// Features: ["extras"]
use mingling::{macros::program_setup, Program};
fn main() {
@@ -154,7 +154,7 @@ fn no_error_setup(program: &mut Program<ThisProgram>) {
### `entry!`
```rust
-// Features: ["extra_macros"]
+// Features: ["extras"]
use mingling::macros::entry;
pack!(EntryHello = Vec<String>);
@@ -174,7 +174,7 @@ Registers an external type as a member of the program group without modifying it
The type's simple name is used as the enum variant, just like `pack!` or `#[derive(Grouped)]`.
```rust
-// Features: ["extra_macros"]
+// Features: ["extras"]
use mingling::macros::group;
use std::num::ParseIntError;
@@ -189,7 +189,7 @@ Creates an error struct with an automatic `name: String` field set to the snake_
of the struct name. Optionally wraps an inner type for additional context.
```rust
-// Features: ["extra_macros"]
+// Features: ["extras"]
use std::path::PathBuf;
// Simple form — only a name field:
diff --git a/examples/example-argument-parse/Cargo.toml b/examples/example-argument-parse/Cargo.toml
index 401ec38..e08adcd 100644
--- a/examples/example-argument-parse/Cargo.toml
+++ b/examples/example-argument-parse/Cargo.toml
@@ -7,6 +7,6 @@ edition = "2024"
path = "../../mingling"
# Enable `parser` features
-features = ["parser", "extra_macros"]
+features = ["parser", "extras"]
[workspace]
diff --git a/examples/example-argument-picker/Cargo.toml b/examples/example-argument-picker/Cargo.toml
index 686b95b..779c00b 100644
--- a/examples/example-argument-picker/Cargo.toml
+++ b/examples/example-argument-picker/Cargo.toml
@@ -7,6 +7,6 @@ edition = "2024"
path = "../../mingling"
# Enable `picker` features
-features = ["picker", "extra_macros"]
+features = ["picker", "extras"]
[workspace]
diff --git a/examples/example-combine-pathf-dispatch-tree/Cargo.toml b/examples/example-combine-pathf-dispatch-tree/Cargo.toml
index 862c5ac..2c866f7 100644
--- a/examples/example-combine-pathf-dispatch-tree/Cargo.toml
+++ b/examples/example-combine-pathf-dispatch-tree/Cargo.toml
@@ -6,7 +6,7 @@ edition = "2024"
[dependencies]
mingling = { path = "../../mingling", features = [
"dispatch_tree",
- "extra_macros",
+ "extras",
"pathf",
] }
diff --git a/examples/example-combine-pathf-dispatch-tree/page.toml b/examples/example-combine-pathf-dispatch-tree/page.toml
index e8f32f2..88557af 100644
--- a/examples/example-combine-pathf-dispatch-tree/page.toml
+++ b/examples/example-combine-pathf-dispatch-tree/page.toml
@@ -6,5 +6,5 @@ category = "advanced"
desc = """
Demonstrates combining the `pathf` and `dispatch_tree` features. Types are defined in submodules and automatically resolved. Requires `dispatch_tree` in both `[dependencies]` and `[build-dependencies]`.
"""
-tags = ["pathf", "dispatch_tree", "extra_macros", "build.rs"]
+tags = ["pathf", "dispatch_tree", "extras", "build.rs"]
files = ["src/main.rs", "src/sub/mod.rs", "build.rs", "Cargo.toml"]
diff --git a/examples/example-combine-pathf-dispatch-tree/src/main.rs b/examples/example-combine-pathf-dispatch-tree/src/main.rs
index 98b3e4c..7407d32 100644
--- a/examples/example-combine-pathf-dispatch-tree/src/main.rs
+++ b/examples/example-combine-pathf-dispatch-tree/src/main.rs
@@ -8,7 +8,7 @@
//! > AND `[build-dependencies]` so that pathf's builder can detect
//! > `__internal_dispatcher_*` types needed by the dispatch tree.
//! >
-//! > Also requires `extra_macros` for the implicit `dispatcher!("hello")` form.
+//! > Also requires `extras` for the implicit `dispatcher!("hello")` form.
//!
//! Run:
//! ```bash
diff --git a/examples/example-command-macro/Cargo.toml b/examples/example-command-macro/Cargo.toml
index b73c2c6..f0596a7 100644
--- a/examples/example-command-macro/Cargo.toml
+++ b/examples/example-command-macro/Cargo.toml
@@ -6,8 +6,8 @@ edition = "2024"
[dependencies.mingling]
path = "../../mingling"
features = [
- # Use `extra_macros` to introduce the `#[command]` macro
- "extra_macros",
+ # Use `extras` to introduce the `#[command]` macro
+ "extras",
# Use `picker` to parse arguments
"picker",
diff --git a/examples/example-custom-pickable/Cargo.toml b/examples/example-custom-pickable/Cargo.toml
index 6e46c8c..9324bd6 100644
--- a/examples/example-custom-pickable/Cargo.toml
+++ b/examples/example-custom-pickable/Cargo.toml
@@ -6,6 +6,6 @@ edition = "2024"
[dependencies.mingling]
path = "../../mingling"
-features = ["parser", "extra_macros"]
+features = ["parser", "extras"]
[workspace]
diff --git a/examples/example-implicit-dispatcher/Cargo.toml b/examples/example-implicit-dispatcher/Cargo.toml
index 3e68e38..2bfa000 100644
--- a/examples/example-implicit-dispatcher/Cargo.toml
+++ b/examples/example-implicit-dispatcher/Cargo.toml
@@ -5,6 +5,6 @@ edition = "2024"
[dependencies.mingling]
path = "../../mingling"
-features = ["extra_macros"]
+features = ["extras"]
[workspace]
diff --git a/examples/example-implicit-dispatcher/page.toml b/examples/example-implicit-dispatcher/page.toml
index 4bea717..12f8839 100644
--- a/examples/example-implicit-dispatcher/page.toml
+++ b/examples/example-implicit-dispatcher/page.toml
@@ -4,7 +4,7 @@ name = "Implicit Dispatcher"
icon = "🫥"
category = "dispatch"
desc = """
-Shows the abbreviated `dispatcher!("cmd.path")` syntax from `extra_macros` that auto-derives struct names from the command path.
+Shows the abbreviated `dispatcher!("cmd.path")` syntax from `extras` that auto-derives struct names from the command path.
"""
tags = ["implicit"]
files = ["src/main.rs", "Cargo.toml"]
diff --git a/examples/example-implicit-dispatcher/src/main.rs b/examples/example-implicit-dispatcher/src/main.rs
index 3dc7f83..340d585 100644
--- a/examples/example-implicit-dispatcher/src/main.rs
+++ b/examples/example-implicit-dispatcher/src/main.rs
@@ -1,6 +1,6 @@
//! Example Implicit Dispatcher
//!
-//! > This example demonstrates how to use the implicit `dispatcher!` definition syntax enabled by `extra_macros`
+//! > This example demonstrates how to use the implicit `dispatcher!` definition syntax enabled by `extras`
use mingling::prelude::*;
diff --git a/examples/example-outside-type/Cargo.toml b/examples/example-outside-type/Cargo.toml
index e2ca5ba..19d4e43 100644
--- a/examples/example-outside-type/Cargo.toml
+++ b/examples/example-outside-type/Cargo.toml
@@ -6,7 +6,7 @@ edition = "2024"
[dependencies.mingling]
path = "../../mingling"
features = [
- "extra_macros",
+ "extras",
]
[workspace]
diff --git a/examples/example-outside-type/page.toml b/examples/example-outside-type/page.toml
index 41e543f..df6dfb1 100644
--- a/examples/example-outside-type/page.toml
+++ b/examples/example-outside-type/page.toml
@@ -6,5 +6,5 @@ category = "advanced"
desc = """
Demonstrates how to use the `group!()` macro to convert an external type into a type recognizable by Mingling
"""
-tags = ["group!", "extra_macros"]
+tags = ["group!", "extras"]
files = ["src/main.rs", "Cargo.toml"]
diff --git a/examples/example-pack-err/Cargo.toml b/examples/example-pack-err/Cargo.toml
index 5d61319..ddab6fd 100644
--- a/examples/example-pack-err/Cargo.toml
+++ b/examples/example-pack-err/Cargo.toml
@@ -10,7 +10,7 @@ serde = { version = "1.0.228", features = ["derive"] }
path = "../../mingling"
features = [
"structural_renderer",
- "extra_macros",
+ "extras",
]
[workspace]
diff --git a/examples/example-pack-err/page.toml b/examples/example-pack-err/page.toml
index 37f2c31..7423087 100644
--- a/examples/example-pack-err/page.toml
+++ b/examples/example-pack-err/page.toml
@@ -6,5 +6,5 @@ category = "macros"
desc = """
Demonstrates how to use the `pack_err!` macro to define error types with automatic `name` field (snake_case at compile time) and optional `info` field. Also shows `--json` serialization when `structural_renderer` is enabled.
"""
-tags = ["pack_err!", "extra_macros", "structural_renderer", "--json"]
+tags = ["pack_err!", "extras", "structural_renderer", "--json"]
files = ["src/main.rs", "Cargo.toml"]
diff --git a/examples/example-repl-basic/Cargo.toml b/examples/example-repl-basic/Cargo.toml
index c20deb9..3289939 100644
--- a/examples/example-repl-basic/Cargo.toml
+++ b/examples/example-repl-basic/Cargo.toml
@@ -5,7 +5,7 @@ edition = "2024"
[dependencies.mingling]
path = "../../mingling"
-features = ["repl", "parser", "extra_macros"]
+features = ["repl", "parser", "extras"]
[dependencies]
just_fmt = "0.1.2"
diff --git a/examples/example-setup/Cargo.toml b/examples/example-setup/Cargo.toml
index 64a0f4e..17398b7 100644
--- a/examples/example-setup/Cargo.toml
+++ b/examples/example-setup/Cargo.toml
@@ -4,6 +4,6 @@ version = "0.1.0"
edition = "2024"
[dependencies]
-mingling = { path = "../../mingling", features = ["extra_macros"] }
+mingling = { path = "../../mingling", features = ["extras"] }
[workspace]
diff --git a/examples/example-setup/page.toml b/examples/example-setup/page.toml
index 9c1fc97..1c8667f 100644
--- a/examples/example-setup/page.toml
+++ b/examples/example-setup/page.toml
@@ -6,5 +6,5 @@ category = "core"
desc = """
Demonstrates how to build a custom `ProgramSetup` with `#[program_setup]` for modular configuration of program behaviour.
"""
-tags = ["#[setup]", "extra_macros"]
+tags = ["#[setup]", "extras"]
files = ["src/main.rs", "Cargo.toml"]
diff --git a/examples/example-unit-test/Cargo.toml b/examples/example-unit-test/Cargo.toml
index a735c5c..97a277c 100644
--- a/examples/example-unit-test/Cargo.toml
+++ b/examples/example-unit-test/Cargo.toml
@@ -4,6 +4,6 @@ version = "0.1.0"
edition = "2024"
[dependencies]
-mingling = { path = "../../mingling", features = ["extra_macros"] }
+mingling = { path = "../../mingling", features = ["extras"] }
[workspace]
diff --git a/examples/example-unit-test/page.toml b/examples/example-unit-test/page.toml
index d8a248c..1d49300 100644
--- a/examples/example-unit-test/page.toml
+++ b/examples/example-unit-test/page.toml
@@ -6,5 +6,5 @@ category = "testing"
desc = """
Shows how to write unit tests for Chain and Renderer functions using the `entry!` macro and assertion helpers.
"""
-tags = ["testing", "extra_macros"]
+tags = ["testing", "extras"]
files = ["src/main.rs", "Cargo.toml"]
diff --git a/examples/full-todolist/Cargo.toml b/examples/full-todolist/Cargo.toml
index e10f0e7..9d6f1a7 100644
--- a/examples/full-todolist/Cargo.toml
+++ b/examples/full-todolist/Cargo.toml
@@ -11,7 +11,7 @@ serde_json = "1.0.150"
path = "../../mingling"
features = [
"parser",
- "extra_macros",
+ "extras",
"structural_renderer",
]
diff --git a/mingling/Cargo.toml b/mingling/Cargo.toml
index 9bf82a7..6f1cc16 100644
--- a/mingling/Cargo.toml
+++ b/mingling/Cargo.toml
@@ -33,7 +33,7 @@ features = [
"parser",
"picker",
"clap",
- "extra_macros",
+ "extras",
]
[features]
@@ -88,13 +88,15 @@ yaml_serde_fmt = ["mingling_core/yaml_serde_fmt"]
toml_serde_fmt = ["mingling_core/toml_serde_fmt"]
ron_serde_fmt = ["mingling_core/ron_serde_fmt"]
-extra_macros = ["mingling_macros/extra_macros"]
+extras = ["mingling_macros/extras"]
# Section only shown in docs.rs
docs_rs = []
-# This is an old name, will be Breaking Change in the future
+# These are old names, will be Breaking Change in the future
+
builds = ["mingling_core/build"]
+extra_macros = ["mingling_macros/extras"]
[dependencies]
mingling_core = { workspace = true, optional = true }
diff --git a/mingling/src/example_docs.rs b/mingling/src/example_docs.rs
index 3e9bd26..6f37a13 100644
--- a/mingling/src/example_docs.rs
+++ b/mingling/src/example_docs.rs
@@ -31,7 +31,7 @@
/// path = "../../mingling"
///
/// # Enable `parser` features
-/// features = ["parser", "extra_macros"]
+/// features = ["parser", "extras"]
///
/// [workspace]
/// ```
@@ -161,7 +161,7 @@ pub mod example_argument_parse {}
/// path = "../../mingling"
///
/// # Enable `picker` features
-/// features = ["picker", "extra_macros"]
+/// features = ["picker", "extras"]
///
/// [workspace]
/// ```
@@ -713,7 +713,7 @@ pub mod example_clap_binding {}
/// > AND `[build-dependencies]` so that pathf's builder can detect
/// > `__internal_dispatcher_*` types needed by the dispatch tree.
/// >
-/// > Also requires `extra_macros` for the implicit `dispatcher!("hello")` form.
+/// > Also requires `extras` for the implicit `dispatcher!("hello")` form.
///
/// Run:
/// ```bash
@@ -735,7 +735,7 @@ pub mod example_clap_binding {}
/// [dependencies]
/// mingling = { path = "../../mingling", features = [
/// "dispatch_tree",
-/// "extra_macros",
+/// "extras",
/// "pathf",
/// ] }
///
@@ -796,8 +796,8 @@ pub mod example_combine_pathf_dispatch_tree {}
/// [dependencies.mingling]
/// path = "../../mingling"
/// features = [
-/// # Use `extra_macros` to introduce the `#[command]` macro
-/// "extra_macros",
+/// # Use `extras` to introduce the `#[command]` macro
+/// "extras",
///
/// # Use `picker` to parse arguments
/// "picker",
@@ -1052,7 +1052,7 @@ pub mod example_completion {}
/// [dependencies.mingling]
/// path = "../../mingling"
///
-/// features = ["parser", "extra_macros"]
+/// features = ["parser", "extras"]
///
/// [workspace]
/// ```
@@ -1780,7 +1780,7 @@ pub mod example_help {}
pub mod example_hook {}
/// Example Implicit Dispatcher
///
-/// > This example demonstrates how to use the implicit `dispatcher!` definition syntax enabled by `extra_macros`
+/// > This example demonstrates how to use the implicit `dispatcher!` definition syntax enabled by `extras`
///
/// Source code (./Cargo.toml)
/// ```toml
@@ -1791,7 +1791,7 @@ pub mod example_hook {}
///
/// [dependencies.mingling]
/// path = "../../mingling"
-/// features = ["extra_macros"]
+/// features = ["extras"]
///
/// [workspace]
/// ```
@@ -1965,7 +1965,7 @@ pub mod example_lazy_resources {}
/// [dependencies.mingling]
/// path = "../../mingling"
/// features = [
-/// "extra_macros",
+/// "extras",
/// ]
///
/// [workspace]
@@ -2096,7 +2096,7 @@ pub mod example_outside_type {}
/// path = "../../mingling"
/// features = [
/// "structural_renderer",
-/// "extra_macros",
+/// "extras",
/// ]
///
/// [workspace]
@@ -2399,7 +2399,7 @@ pub mod example_pathfinder {}
///
/// [dependencies.mingling]
/// path = "../../mingling"
-/// features = ["repl", "parser", "extra_macros"]
+/// features = ["repl", "parser", "extras"]
///
/// [dependencies]
/// just_fmt = "0.1.2"
@@ -2691,7 +2691,7 @@ pub mod example_resources {}
/// edition = "2024"
///
/// [dependencies]
-/// mingling = { path = "../../mingling", features = ["extra_macros"] }
+/// mingling = { path = "../../mingling", features = ["extras"] }
///
/// [workspace]
/// ```
@@ -2843,7 +2843,7 @@ pub mod example_structural_renderer {}
/// edition = "2024"
///
/// [dependencies]
-/// mingling = { path = "../../mingling", features = ["extra_macros"] }
+/// mingling = { path = "../../mingling", features = ["extras"] }
///
/// [workspace]
/// ```
diff --git a/mingling/src/features.rs b/mingling/src/features.rs
index 0dde333..d1fcbd2 100644
--- a/mingling/src/features.rs
+++ b/mingling/src/features.rs
@@ -130,6 +130,17 @@ pub const MINGLING_EXTRA_MACROS: bool = false;
#[cfg(feature = "extra_macros")]
#[allow(unused)]
pub const MINGLING_EXTRA_MACROS: bool = true;
+/// Whether the `extras` feature is enabled
+/// Current: `disabled`
+#[cfg(not(feature = "extras"))]
+#[allow(unused)]
+pub const MINGLING_EXTRAS: bool = false;
+
+/// Whether the `extras` feature is enabled
+/// Current: `enabled`
+#[cfg(feature = "extras")]
+#[allow(unused)]
+pub const MINGLING_EXTRAS: bool = true;
/// Whether the `json_serde_fmt` feature is enabled
/// Current: `disabled`
#[cfg(not(feature = "json_serde_fmt"))]
diff --git a/mingling/src/lib.rs b/mingling/src/lib.rs
index 3852191..c9c6d22 100644
--- a/mingling/src/lib.rs
+++ b/mingling/src/lib.rs
@@ -24,10 +24,6 @@ pub mod parser;
#[cfg(feature = "picker")]
pub mod picker;
-/// Functionality when combining `picker` and `comp`
-#[cfg(all(feature = "picker", feature = "comp"))]
-pub mod picker_comp;
-
mod constants;
/// Constants used throughout the Mingling framework.
@@ -53,29 +49,29 @@ pub mod macros {
pub use arg_picker::macros::*;
pub use mingling_macros::buffer;
pub use mingling_macros::chain;
- #[cfg(feature = "extra_macros")]
+ #[cfg(feature = "extras")]
pub use mingling_macros::command;
#[cfg(feature = "comp")]
pub use mingling_macros::completion;
pub use mingling_macros::dispatcher;
#[cfg(feature = "clap")]
pub use mingling_macros::dispatcher_clap;
- #[cfg(feature = "extra_macros")]
+ #[cfg(feature = "extras")]
pub use mingling_macros::empty_result;
- #[cfg(feature = "extra_macros")]
+ #[cfg(feature = "extras")]
pub use mingling_macros::entry;
pub use mingling_macros::gen_program;
- #[cfg(feature = "extra_macros")]
+ #[cfg(feature = "extras")]
pub use mingling_macros::group;
- #[cfg(all(feature = "structural_renderer", feature = "extra_macros"))]
+ #[cfg(all(feature = "structural_renderer", feature = "extras"))]
pub use mingling_macros::group_structural;
pub use mingling_macros::help;
pub use mingling_macros::mlint;
pub use mingling_macros::node;
pub use mingling_macros::pack;
- #[cfg(feature = "extra_macros")]
+ #[cfg(feature = "extras")]
pub use mingling_macros::pack_err;
- #[cfg(all(feature = "structural_renderer", feature = "extra_macros"))]
+ #[cfg(all(feature = "structural_renderer", feature = "extras"))]
pub use mingling_macros::pack_err_structural;
#[cfg(feature = "structural_renderer")]
pub use mingling_macros::pack_structural;
@@ -86,7 +82,7 @@ pub mod macros {
pub use mingling_macros::program_fallback_gen;
#[doc(hidden)]
pub use mingling_macros::program_final_gen;
- #[cfg(feature = "extra_macros")]
+ #[cfg(feature = "extras")]
pub use mingling_macros::program_setup;
pub use mingling_macros::r_append;
pub use mingling_macros::r_eprint;
@@ -103,14 +99,14 @@ pub mod macros {
pub use mingling_macros::register_renderer;
#[doc(hidden)]
pub use mingling_macros::register_type;
- #[cfg(feature = "extra_macros")]
+ #[cfg(feature = "extras")]
pub use mingling_macros::render_route;
pub use mingling_macros::renderer;
- #[cfg(feature = "extra_macros")]
+ #[cfg(feature = "extras")]
pub use mingling_macros::renderify;
- #[cfg(feature = "extra_macros")]
+ #[cfg(feature = "extras")]
pub use mingling_macros::route;
- #[cfg(feature = "extra_macros")]
+ #[cfg(feature = "extras")]
pub use mingling_macros::routeify;
#[cfg(feature = "comp")]
pub use mingling_macros::suggest;
@@ -181,24 +177,24 @@ pub mod prelude {
pub use crate::Routable;
#[cfg(feature = "macros")]
pub use crate::macros::chain;
- #[cfg(all(feature = "extra_macros", feature = "macros"))]
+ #[cfg(all(feature = "extras", feature = "macros"))]
pub use crate::macros::command;
#[cfg(feature = "macros")]
pub use crate::macros::dispatcher;
- #[cfg(all(feature = "extra_macros", feature = "macros"))]
+ #[cfg(all(feature = "extras", feature = "macros"))]
pub use crate::macros::empty_result;
#[cfg(feature = "macros")]
pub use crate::macros::gen_program;
#[cfg(feature = "macros")]
pub use crate::macros::pack;
- #[cfg(all(feature = "extra_macros", feature = "macros"))]
+ #[cfg(all(feature = "extras", feature = "macros"))]
pub use crate::macros::pack_err;
#[cfg(feature = "macros")]
pub use crate::macros::renderer;
#[cfg(all(
feature = "macros",
feature = "structural_renderer",
- feature = "extra_macros"
+ feature = "extras"
))]
pub use mingling_macros::pack_err_structural;
#[cfg(all(feature = "macros", feature = "structural_renderer"))]
diff --git a/mingling/src/picker_comp.rs b/mingling/src/picker_comp.rs
deleted file mode 100644
index 26b0b5a..0000000
--- a/mingling/src/picker_comp.rs
+++ /dev/null
@@ -1,52 +0,0 @@
-use arg_picker::{Pickable, PickerArg, PickerArgInfo, parselib::ParserStyle};
-use mingling_core::{Suggest, SuggestItem};
-
-/// Trait for converting picker arguments into `Suggest` items for autocompletion.
-///
-/// This trait is implemented for `PickerArg` references and provides methods to
-/// generate completion suggestions with optional descriptions.
-pub trait PickerArgSuggest {
- #[doc(hidden)]
- fn into_suggest_raw(self, description: Option<&String>) -> Suggest;
-
- /// Converts the picker argument into a `Suggest` with the given description.
- ///
- /// The description is used when the suggestion item supports additional text,
- /// such as `SuggestItem::WithDescription`.
- fn into_suggest_with_desc(self, description: impl Into<String>) -> Suggest
- where
- Self: Sized,
- {
- let desc = description.into();
- self.into_suggest_raw(Some(&desc))
- }
-
- /// Converts the picker argument into a `Suggest` without a description.
- ///
- /// The resulting suggestion will use `SuggestItem::Simple` for each possible flag.
- fn into_suggest(self) -> Suggest
- where
- Self: Sized,
- {
- self.into_suggest_raw(None)
- }
-}
-
-impl<'a, T> PickerArgSuggest for &'a PickerArg<'a, T>
-where
- T: Pickable<'a>,
-{
- fn into_suggest_raw(self, description: Option<&String>) -> Suggest {
- let mut suggest = Suggest::new();
- let info = PickerArgInfo::from(self);
- let possible_flags =
- arg_picker::parselib::build_possible_flags(ParserStyle::global_style(), &info);
- for flag in possible_flags {
- match description {
- Some(desc) => suggest.insert(SuggestItem::WithDescription(flag, desc.clone())),
- None => suggest.insert(SuggestItem::Simple(flag)),
- };
- }
- suggest
- }
-}
diff --git a/mingling_cli/Cargo.toml b/mingling_cli/Cargo.toml
index 330ef5a..9ee8fa0 100644
--- a/mingling_cli/Cargo.toml
+++ b/mingling_cli/Cargo.toml
@@ -22,7 +22,7 @@ path = "src/main.rs"
[dependencies.mingling]
path = "../mingling"
features = [
- "extra_macros",
+ "extras",
"picker",
"pathf",
"async",
diff --git a/mingling_core/src/comp/suggest.rs b/mingling_core/src/comp/suggest.rs
index 88fa5fc..dda5026 100644
--- a/mingling_core/src/comp/suggest.rs
+++ b/mingling_core/src/comp/suggest.rs
@@ -56,6 +56,42 @@ impl Suggest {
(suggest, _) => suggest,
}
}
+
+ /// Adds multiple simple suggestions (without descriptions) to the `Suggest` set.
+ ///
+ /// Each item produced by the iterator is wrapped in a [`SuggestItem::Simple`]
+ /// variant and inserted into the underlying `BTreeSet`.
+ ///
+ /// # Arguments
+ ///
+ /// * `items` — A collection of suggestion strings to add.
+ pub fn add_suggest(&mut self, items: impl Into<Vec<String>>) {
+ for item in items.into() {
+ self.insert(SuggestItem::Simple(item));
+ }
+ }
+
+ /// Adds multiple suggestions with a shared description to the `Suggest` set.
+ ///
+ /// Each item produced by the iterator is wrapped in a
+ /// [`SuggestItem::WithDescription`] variant using the provided description,
+ /// and inserted into the underlying `BTreeSet`.
+ ///
+ /// # Arguments
+ ///
+ /// * `items` — A collection of suggestion strings to add.
+ /// * `desc` — The description to attach to each suggestion. Must implement
+ /// `Into<String>`.
+ pub fn add_suggest_with_description(
+ &mut self,
+ items: impl Into<Vec<String>>,
+ desc: impl Into<String>,
+ ) {
+ let desc_str = desc.into();
+ for item in items.into() {
+ self.insert(SuggestItem::WithDescription(item, desc_str.clone()));
+ }
+ }
}
impl<T> From<T> for Suggest
diff --git a/mingling_core/src/program/collection.rs b/mingling_core/src/program/collection.rs
index 14705ac..fa062cf 100644
--- a/mingling_core/src/program/collection.rs
+++ b/mingling_core/src/program/collection.rs
@@ -29,7 +29,7 @@ pub trait ProgramCollect {
/// Result type for an empty chain result
///
- /// When the `extra_macros` feature is enabled,
+ /// When the `extras` feature is enabled,
/// you can use the `empty_result!()` macro to create this
type ResultEmpty: Grouped<Self::Enum>;
diff --git a/mingling_core/tests/test-all/Cargo.toml b/mingling_core/tests/test-all/Cargo.toml
index a63b6e6..272f1d2 100644
--- a/mingling_core/tests/test-all/Cargo.toml
+++ b/mingling_core/tests/test-all/Cargo.toml
@@ -14,7 +14,7 @@ mingling = { path = "../../../mingling", features = [
"repl",
"dispatch_tree",
"parser",
- "extra_macros",
+ "extras",
] }
tokio = { version = "1", features = ["full"] }
serde = { version = "1", features = ["derive"] }
diff --git a/mingling_core/tests/test-repl/Cargo.toml b/mingling_core/tests/test-repl/Cargo.toml
index c4c83ce..0924943 100644
--- a/mingling_core/tests/test-repl/Cargo.toml
+++ b/mingling_core/tests/test-repl/Cargo.toml
@@ -7,4 +7,4 @@ publish = false
[workspace]
[dependencies]
-mingling = { path = "../../../mingling", features = ["repl", "extra_macros"] }
+mingling = { path = "../../../mingling", features = ["repl", "extras"] }
diff --git a/mingling_macros/Cargo.toml b/mingling_macros/Cargo.toml
index 1191015..137213a 100644
--- a/mingling_macros/Cargo.toml
+++ b/mingling_macros/Cargo.toml
@@ -25,7 +25,7 @@ structural_renderer = []
repl = []
pathf = []
-extra_macros = []
+extras = []
[dependencies]
syn.workspace = true
diff --git a/mingling_macros/src/attr.rs b/mingling_macros/src/attr.rs
index 8c17878..54fe2f1 100644
--- a/mingling_macros/src/attr.rs
+++ b/mingling_macros/src/attr.rs
@@ -1,5 +1,5 @@
pub(crate) mod chain;
-#[cfg(feature = "extra_macros")]
+#[cfg(feature = "extras")]
pub(crate) mod command;
#[cfg(feature = "comp")]
pub(crate) mod completion;
@@ -7,6 +7,6 @@ pub(crate) mod completion;
pub(crate) mod dispatcher_clap;
pub(crate) mod help;
pub(crate) mod mlint;
-#[cfg(feature = "extra_macros")]
+#[cfg(feature = "extras")]
pub(crate) mod program_setup;
pub(crate) mod renderer;
diff --git a/mingling_macros/src/extensions.rs b/mingling_macros/src/extensions.rs
index c2fdb30..f4a6fde 100644
--- a/mingling_macros/src/extensions.rs
+++ b/mingling_macros/src/extensions.rs
@@ -10,11 +10,11 @@ use syn::parse::{Parse, ParseStream};
use syn::{Ident, Token};
/// Extension: `#[routeify]` — transforms `expr?` into `route!(expr)`.
-#[cfg(feature = "extra_macros")]
+#[cfg(feature = "extras")]
pub(crate) mod routeify;
/// Extension: `#[renderify]` — transforms `expr?` into `render_route!(expr)`.
-#[cfg(feature = "extra_macros")]
+#[cfg(feature = "extras")]
pub(crate) mod renderify;
/// Extension: `#[buffer]` — wraps a unit-returning function to return `RenderResult`.
diff --git a/mingling_macros/src/func.rs b/mingling_macros/src/func.rs
index d836b38..9e0e15f 100644
--- a/mingling_macros/src/func.rs
+++ b/mingling_macros/src/func.rs
@@ -1,18 +1,18 @@
pub(crate) mod dispatcher;
-#[cfg(feature = "extra_macros")]
+#[cfg(feature = "extras")]
pub(crate) mod empty_result;
-#[cfg(feature = "extra_macros")]
+#[cfg(feature = "extras")]
pub(crate) mod entry;
pub(crate) mod gen_program;
-#[cfg(feature = "extra_macros")]
+#[cfg(feature = "extras")]
pub(crate) mod group;
-#[cfg(all(feature = "structural_renderer", feature = "extra_macros"))]
+#[cfg(all(feature = "structural_renderer", feature = "extras"))]
pub(crate) mod group_structural;
pub(crate) mod node;
pub(crate) mod pack;
-#[cfg(feature = "extra_macros")]
+#[cfg(feature = "extras")]
pub(crate) mod pack_err;
-#[cfg(all(feature = "structural_renderer", feature = "extra_macros"))]
+#[cfg(all(feature = "structural_renderer", feature = "extras"))]
pub(crate) mod pack_err_structural;
#[cfg(feature = "structural_renderer")]
pub(crate) mod pack_structural;
@@ -30,9 +30,9 @@ pub(crate) mod register_dispatcher;
pub(crate) mod register_help;
pub(crate) mod register_renderer;
pub(crate) mod register_type;
-#[cfg(feature = "extra_macros")]
+#[cfg(feature = "extras")]
pub(crate) mod render_route;
-#[cfg(feature = "extra_macros")]
+#[cfg(feature = "extras")]
pub(crate) mod route;
#[cfg(feature = "comp")]
pub(crate) mod suggest;
diff --git a/mingling_macros/src/func/dispatcher.rs b/mingling_macros/src/func/dispatcher.rs
index ef02618..a9e2464 100644
--- a/mingling_macros/src/func/dispatcher.rs
+++ b/mingling_macros/src/func/dispatcher.rs
@@ -12,7 +12,7 @@ enum DispatcherChainInput {
command_struct: Ident,
pack: Ident,
},
- #[cfg(feature = "extra_macros")]
+ #[cfg(feature = "extras")]
Auto {
cmd_attrs: Vec<Attribute>,
command_name: syn::LitStr,
@@ -30,14 +30,14 @@ impl Parse for DispatcherChainInput {
// Check if this is the abbreviated form: just "command_name" without ", CMD => Entry"
if input.is_empty() {
- #[cfg(feature = "extra_macros")]
+ #[cfg(feature = "extras")]
{
return Ok(DispatcherChainInput::Auto {
cmd_attrs,
command_name,
});
}
- #[cfg(not(feature = "extra_macros"))]
+ #[cfg(not(feature = "extras"))]
{
return Err(syn::Error::new(
command_name.span(),
@@ -74,7 +74,7 @@ pub(crate) fn dispatcher(input: TokenStream) -> TokenStream {
// Parse the input
let dispatcher_input = syn::parse_macro_input!(input as DispatcherChainInput);
- #[cfg(not(feature = "extra_macros"))]
+ #[cfg(not(feature = "extras"))]
let (command_name, command_struct, pack, cmd_attrs, entry_attrs) = match dispatcher_input {
DispatcherChainInput::Default {
cmd_attrs,
@@ -85,7 +85,7 @@ pub(crate) fn dispatcher(input: TokenStream) -> TokenStream {
} => (command_name, command_struct, pack, cmd_attrs, entry_attrs),
};
- #[cfg(feature = "extra_macros")]
+ #[cfg(feature = "extras")]
let (command_name, command_struct, pack, cmd_attrs, entry_attrs) = match dispatcher_input {
DispatcherChainInput::Default {
cmd_attrs,
diff --git a/mingling_macros/src/func/suggest.rs b/mingling_macros/src/func/suggest.rs
index 85f1afe..6613a98 100644
--- a/mingling_macros/src/func/suggest.rs
+++ b/mingling_macros/src/func/suggest.rs
@@ -2,15 +2,15 @@ use proc_macro::TokenStream;
use quote::quote;
use syn::parse::{Parse, ParseStream};
use syn::punctuated::Punctuated;
-use syn::{Expr, LitStr, Token, parse_macro_input};
+use syn::{Expr, Token, parse_macro_input};
struct SuggestInput {
items: Punctuated<SuggestItem, Token![,]>,
}
enum SuggestItem {
- WithDesc(Box<(LitStr, Expr)>), // "-i" = "Insert something"
- Simple(LitStr), // "-I"
+ WithDesc(Box<(Expr, Expr)>), // "-i" = "Insert something"
+ Simple(Expr), // "-I"
}
impl Parse for SuggestInput {
@@ -22,7 +22,7 @@ impl Parse for SuggestInput {
impl Parse for SuggestItem {
fn parse(input: ParseStream) -> syn::Result<Self> {
- let key: LitStr = input.parse()?;
+ let key: Expr = input.parse()?;
if input.peek(Token![:]) {
let _colon: Token![:] = input.parse()?;
@@ -34,36 +34,55 @@ impl Parse for SuggestItem {
}
}
+/// 判断表达式是否是一个纯字符串字面量(仅由一对引号包裹)
+fn is_pure_lit_str(expr: &Expr) -> bool {
+ matches!(expr, Expr::Lit(lit) if matches!(lit.lit, syn::Lit::Str(_)))
+}
+
#[cfg(feature = "comp")]
pub(crate) fn suggest(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as SuggestInput);
let mut items = Vec::new();
+ let mut simple_items = Vec::new();
for item in input.items {
match item {
SuggestItem::WithDesc(boxed) => {
let (key, value) = *boxed;
- items.push(quote! {
- ::mingling::SuggestItem::new_with_desc(#key.to_string(), #value.to_string())
- });
+ if is_pure_lit_str(&key) {
+ items.push(quote! {
+ vec![#key .to_string()], #value
+ });
+ } else {
+ items.push(quote! {
+ #key, #value
+ });
+ }
}
SuggestItem::Simple(key) => {
- items.push(quote! {
- ::mingling::SuggestItem::new(#key.to_string())
- });
+ if is_pure_lit_str(&key) {
+ simple_items.push(quote! {
+ vec![#key .to_string()]
+ });
+ } else {
+ simple_items.push(quote! {
+ #key
+ });
+ }
}
}
}
- let expanded = if items.is_empty() {
+ let expanded = if items.is_empty() && simple_items.is_empty() {
quote! {
::mingling::Suggest::new()
}
} else {
quote! {{
let mut suggest = ::mingling::Suggest::new();
- #(suggest.insert(#items);)*
+ #(suggest.add_suggest_with_description(#items);)*
+ #(suggest.add_suggest(#simple_items);)*
suggest
}}
};
diff --git a/mingling_macros/src/lib.rs b/mingling_macros/src/lib.rs
index ae874af..b6656da 100644
--- a/mingling_macros/src/lib.rs
+++ b/mingling_macros/src/lib.rs
@@ -100,10 +100,10 @@
//! |---------|---------------|
//! | `clap` | `dispatcher_clap!` |
//! | `comp` | [`#[completion]`](attr.completion.html), `suggest!`, `suggest_enum!` |
-//! | `extra_macros` | `entry!`, `empty_result!`, `route!`, [`#[program_setup]`](attr.program_setup.html), `group!` |
+//! | `extras` | `entry!`, `empty_result!`, `route!`, [`#[program_setup]`](attr.program_setup.html), `group!` |
//! | `dispatch_tree` | `register_dispatcher!` (enables trie-based command dispatch) |
//! | `structural_renderer` | `#[derive(StructuralData)]`, `pack_structural!`, `pack_err_structural!`, `group_structural!` |
-//! | `structural_renderer` + `extra_macros` | `group_structural!`, `pack_err_structural!` |
+//! | `structural_renderer` + `extras` | `group_structural!`, `pack_err_structural!` |
//! | `async` | Enables async `#[chain]` functions |
//! | `repl` | Enables REPL execution loop |
//!
@@ -163,15 +163,15 @@ mod utils;
use attr::completion;
#[cfg(feature = "clap")]
use attr::dispatcher_clap;
-#[cfg(feature = "extra_macros")]
+#[cfg(feature = "extras")]
use attr::program_setup;
use attr::{chain, help, renderer};
use derive::{enum_tag, grouped};
-#[cfg(feature = "extra_macros")]
+#[cfg(feature = "extras")]
use func::entry;
-#[cfg(feature = "extra_macros")]
+#[cfg(feature = "extras")]
pub(crate) use func::group as group_impl;
-#[cfg(feature = "extra_macros")]
+#[cfg(feature = "extras")]
use func::pack_err;
#[cfg(feature = "comp")]
use func::suggest;
@@ -293,7 +293,7 @@ fn entry_has_variant(entry: &str, variant_name: &str) -> bool {
///
/// - The type must be accessible at the call site (imported or fully qualified).
/// - The alias name (if provided) must not conflict with existing types.
-#[cfg(feature = "extra_macros")]
+#[cfg(feature = "extras")]
#[proc_macro]
pub fn group(input: TokenStream) -> TokenStream {
group_impl::group_macro(input)
@@ -309,8 +309,8 @@ pub fn group(input: TokenStream) -> TokenStream {
/// group_structural!(IoError = std::io::Error);
/// ```
///
-/// Requires the `structural_renderer` and `extra_macros` features.
-#[cfg(all(feature = "structural_renderer", feature = "extra_macros"))]
+/// Requires the `structural_renderer` and `extras` features.
+#[cfg(all(feature = "structural_renderer", feature = "extras"))]
#[proc_macro]
pub fn group_structural(input: TokenStream) -> TokenStream {
func::group_structural::group_structural(input)
@@ -490,8 +490,8 @@ pub fn pack_structural(input: TokenStream) -> TokenStream {
/// When the `structural_renderer` feature is enabled, the struct also gets
/// `#[derive(serde::Serialize)]`.
///
-/// This macro is only available with the `extra_macros` feature.
-#[cfg(feature = "extra_macros")]
+/// This macro is only available with the `extras` feature.
+#[cfg(feature = "extras")]
#[proc_macro]
pub fn pack_err(input: TokenStream) -> TokenStream {
pack_err::pack_err(input)
@@ -507,8 +507,8 @@ pub fn pack_err(input: TokenStream) -> TokenStream {
/// pack_err_structural!(ErrorNotDir = PathBuf);
/// ```
///
-/// Requires the `structural_renderer` and `extra_macros` features.
-#[cfg(all(feature = "structural_renderer", feature = "extra_macros"))]
+/// Requires the `structural_renderer` and `extras` features.
+#[cfg(all(feature = "structural_renderer", feature = "extras"))]
#[proc_macro]
pub fn pack_err_structural(input: TokenStream) -> TokenStream {
func::pack_err_structural::pack_err_structural(input)
@@ -568,7 +568,7 @@ pub fn pack_err_structural(input: TokenStream) -> TokenStream {
/// value.to_chain()
/// }
/// ```
-#[cfg(feature = "extra_macros")]
+#[cfg(feature = "extras")]
#[proc_macro]
pub fn route(input: TokenStream) -> TokenStream {
func::route::route(input)
@@ -611,7 +611,7 @@ pub fn route(input: TokenStream) -> TokenStream {
/// Ok(RenderResult::new())
/// }
/// ```
-#[cfg(feature = "extra_macros")]
+#[cfg(feature = "extras")]
#[proc_macro]
pub fn render_route(input: TokenStream) -> TokenStream {
func::render_route::render_route(input)
@@ -665,7 +665,7 @@ pub fn render_route(input: TokenStream) -> TokenStream {
///
/// [`ResultEmpty`]: https://docs.rs/mingling/latest/mingling/type.ResultEmpty.html
/// [`ChainProcess`]: https://docs.rs/mingling/latest/mingling/enum.ChainProcess.html
-#[cfg(feature = "extra_macros")]
+#[cfg(feature = "extras")]
#[proc_macro]
pub fn empty_result(input: TokenStream) -> TokenStream {
func::empty_result::empty_result(input)
@@ -692,9 +692,9 @@ pub fn empty_result(input: TokenStream) -> TokenStream {
/// dispatcher!(MyProgram, "command.path", CommandStruct => EntryStruct);
/// ```
///
-/// ## Abbreviated syntax (requires `extra_macros` feature)
+/// ## Abbreviated syntax (requires `extras` feature)
///
-/// When the `extra_macros` feature is enabled, the `CommandStruct => EntryStruct`
+/// When the `extras` feature is enabled, the `CommandStruct => EntryStruct`
/// portion can be omitted. Struct names are auto-derived from the command path
/// using `PascalCase` conversion:
///
@@ -721,7 +721,7 @@ pub fn empty_result(input: TokenStream) -> TokenStream {
/// // With explicit program:
/// dispatcher!(MyApp, "status", StatusCommand => StatusEntry);
///
-/// // Abbreviated form (extra_macros required):
+/// // Abbreviated form (extras required):
/// // dispatcher!("remote.add"); // → CMDRemoteAdd, EntryRemoteAdd
/// ```
///
@@ -1094,7 +1094,7 @@ pub fn completion(attr: TokenStream, item: TokenStream) -> TokenStream {
/// - The function must have exactly one parameter of type `&mut Program<G>`.
/// - The function must return `()`.
/// - The function cannot be async.
-#[cfg(feature = "extra_macros")]
+#[cfg(feature = "extras")]
#[proc_macro_attribute]
pub fn program_setup(attr: TokenStream, item: TokenStream) -> TokenStream {
program_setup::setup_attr(attr, item)
@@ -1102,7 +1102,7 @@ pub fn program_setup(attr: TokenStream, item: TokenStream) -> TokenStream {
/// Declares a command from a plain function.
///
-/// **This macro is only available with the `extra_macros` feature.**
+/// **This macro is only available with the `extras` feature.**
///
/// The `#[command]` attribute converts a function taking `Vec<String>` into a
/// Mingling command by:
@@ -1181,7 +1181,7 @@ pub fn program_setup(attr: TokenStream, item: TokenStream) -> TokenStream {
/// - The function must have at least one parameter (the `Vec<String>` entry argument).
/// - The function must not have a `self` parameter.
/// - Visibility (`pub` etc.) and `async` are preserved on the original function.
-#[cfg(feature = "extra_macros")]
+#[cfg(feature = "extras")]
#[proc_macro_attribute]
pub fn command(attr: TokenStream, item: TokenStream) -> TokenStream {
attr::command::command_attr(attr, item)
@@ -1273,7 +1273,7 @@ pub fn dispatcher_clap(attr: TokenStream, item: TokenStream) -> TokenStream {
///
/// - `pack!` — For creating the wrapper types used with `entry!`.
/// - `dispatcher!` — Which implicitly creates entry types via `pack!`.
-#[cfg(feature = "extra_macros")]
+#[cfg(feature = "extras")]
#[proc_macro]
pub fn entry(input: TokenStream) -> TokenStream {
entry::entry(input)
@@ -1438,7 +1438,7 @@ pub fn mlint(attr: TokenStream, item: TokenStream) -> TokenStream {
/// StateCalculate { number_a: a, operator: op, ... }.to_chain()
/// }
/// ```
-#[cfg(feature = "extra_macros")]
+#[cfg(feature = "extras")]
#[proc_macro_attribute]
pub fn routeify(attr: TokenStream, item: TokenStream) -> TokenStream {
extensions::routeify::routeify_impl(attr, item)
@@ -1464,7 +1464,7 @@ pub fn routeify(attr: TokenStream, item: TokenStream) -> TokenStream {
/// Ok(RenderResult::new())
/// }
/// ```
-#[cfg(feature = "extra_macros")]
+#[cfg(feature = "extras")]
#[proc_macro_attribute]
pub fn renderify(attr: TokenStream, item: TokenStream) -> TokenStream {
extensions::renderify::renderify_impl(attr, item)