aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author魏曹先生 <1992414357@qq.com>2026-07-17 11:08:07 +0800
committer魏曹先生 <1992414357@qq.com>2026-07-17 11:11:28 +0800
commit79ec6878877f0fd9246d67d3cd4f8cc2d1200150 (patch)
treee3cd8cfc7ef5cd2a6a7ceb93d9a4b1764fa21b61
parente6136f22cff446b16dbebf3b26a6fdea6dbc0e83 (diff)
refactor: rename `mingling_picker` to `arg_picker`
-rw-r--r--.vscode/settings.json18
-rw-r--r--.zed/settings.json34
-rw-r--r--CHANGELOG.md334
-rw-r--r--CONTRIBUTING.md54
-rw-r--r--Cargo.lock38
-rw-r--r--Cargo.toml9
-rw-r--r--arg_picker/Cargo.toml17
-rw-r--r--arg_picker/README.md (renamed from mingling_picker/README.md)10
-rw-r--r--arg_picker/src/arg.rs (renamed from mingling_picker/src/arg.rs)0
-rw-r--r--arg_picker/src/builtin.rs (renamed from mingling_picker/src/builtin.rs)0
-rw-r--r--arg_picker/src/builtin/pick_bool.rs (renamed from mingling_picker/src/builtin/pick_bool.rs)0
-rw-r--r--arg_picker/src/builtin/pick_flag.rs (renamed from mingling_picker/src/builtin/pick_flag.rs)0
-rw-r--r--arg_picker/src/builtin/pick_numbers.rs (renamed from mingling_picker/src/builtin/pick_numbers.rs)0
-rw-r--r--arg_picker/src/builtin/pick_string.rs (renamed from mingling_picker/src/builtin/pick_string.rs)0
-rw-r--r--arg_picker/src/corebind.rs (renamed from mingling_picker/src/corebind.rs)0
-rw-r--r--arg_picker/src/corebind/entry_picker.rs (renamed from mingling_picker/src/corebind/entry_picker.rs)0
-rw-r--r--arg_picker/src/infos.rs (renamed from mingling_picker/src/infos.rs)22
-rw-r--r--arg_picker/src/lib.rs (renamed from mingling_picker/src/lib.rs)6
-rw-r--r--arg_picker/src/parselib.rs (renamed from mingling_picker/src/parselib.rs)0
-rw-r--r--arg_picker/src/parselib/arg_matcher.rs (renamed from mingling_picker/src/parselib/arg_matcher.rs)0
-rw-r--r--arg_picker/src/parselib/flag_matcher.rs (renamed from mingling_picker/src/parselib/flag_matcher.rs)0
-rw-r--r--arg_picker/src/parselib/multi_arg_matcher.rs (renamed from mingling_picker/src/parselib/multi_arg_matcher.rs)0
-rw-r--r--arg_picker/src/parselib/pos_matcher.rs (renamed from mingling_picker/src/parselib/pos_matcher.rs)0
-rw-r--r--arg_picker/src/parselib/single_matcher.rs (renamed from mingling_picker/src/parselib/single_matcher.rs)0
-rw-r--r--arg_picker/src/parselib/style.rs (renamed from mingling_picker/src/parselib/style.rs)10
-rw-r--r--arg_picker/src/parselib/utils.rs (renamed from mingling_picker/src/parselib/utils.rs)0
-rw-r--r--arg_picker/src/pickable.rs (renamed from mingling_picker/src/pickable.rs)0
-rw-r--r--arg_picker/src/pickable/multi_pickable.rs (renamed from mingling_picker/src/pickable/multi_pickable.rs)0
-rw-r--r--arg_picker/src/pickable/single_pickable.rs (renamed from mingling_picker/src/pickable/single_pickable.rs)0
-rw-r--r--arg_picker/src/picker.rs (renamed from mingling_picker/src/picker.rs)2
-rw-r--r--arg_picker/src/picker/parse.rs (renamed from mingling_picker/src/picker/parse.rs)2
-rw-r--r--arg_picker/src/picker/patterns.rs (renamed from mingling_picker/src/picker/patterns.rs)2
-rw-r--r--arg_picker/src/picker/result.rs (renamed from mingling_picker/src/picker/result.rs)2
-rw-r--r--arg_picker/src/value.rs (renamed from mingling_picker/src/value.rs)0
-rw-r--r--arg_picker/src/value/flag.rs (renamed from mingling_picker/src/value/flag.rs)6
-rw-r--r--arg_picker/src/value/vec_until.rs (renamed from mingling_picker/src/value/vec_until.rs)0
-rw-r--r--arg_picker/test/Cargo.lock (renamed from mingling_picker/test/Cargo.lock)36
-rw-r--r--arg_picker/test/Cargo.toml (renamed from mingling_picker/test/Cargo.toml)4
-rw-r--r--arg_picker/test/src/lib.rs (renamed from mingling_picker/test/src/lib.rs)2
-rw-r--r--arg_picker/test/src/test.rs (renamed from mingling_picker/test/src/test.rs)0
-rw-r--r--arg_picker/test/src/test/arg_matcher_test.rs (renamed from mingling_picker/test/src/test/arg_matcher_test.rs)4
-rw-r--r--arg_picker/test/src/test/basic_test.rs (renamed from mingling_picker/test/src/test/basic_test.rs)2
-rw-r--r--arg_picker/test/src/test/multi_arg_test.rs (renamed from mingling_picker/test/src/test/multi_arg_test.rs)25
-rw-r--r--arg_picker/test/src/test/multi_value_test.rs (renamed from mingling_picker/test/src/test/multi_value_test.rs)4
-rw-r--r--arg_picker/test/src/test/pos_matcher_test.rs (renamed from mingling_picker/test/src/test/pos_matcher_test.rs)4
-rw-r--r--arg_picker/test/src/test/priority_test.rs (renamed from mingling_picker/test/src/test/priority_test.rs)4
-rw-r--r--arg_picker/test/src/test/route_test.rs (renamed from mingling_picker/test/src/test/route_test.rs)2
-rw-r--r--arg_picker/test/src/test/style_test.rs (renamed from mingling_picker/test/src/test/style_test.rs)8
-rw-r--r--arg_picker/test/src/test/value_flag_test.rs (renamed from mingling_picker/test/src/test/value_flag_test.rs)4
-rw-r--r--arg_picker/test/src/test/value_string_test.rs (renamed from mingling_picker/test/src/test/value_string_test.rs)2
-rw-r--r--arg_picker_macros/Cargo.toml (renamed from mingling_picker_macros/Cargo.toml)10
-rw-r--r--arg_picker_macros/README.md (renamed from mingling_picker_macros/README.md)0
-rw-r--r--arg_picker_macros/src/arg.rs (renamed from mingling_picker_macros/src/arg.rs)2
-rw-r--r--arg_picker_macros/src/internal_repeat.rs (renamed from mingling_picker_macros/src/internal_repeat.rs)0
-rw-r--r--arg_picker_macros/src/lib.rs (renamed from mingling_picker_macros/src/lib.rs)2
-rw-r--r--mingling/Cargo.toml4
-rw-r--r--mingling/src/lib.rs12
-rw-r--r--mingling_picker/Cargo.toml17
58 files changed, 360 insertions, 354 deletions
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 7472e1c..389a476 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,11 +1,11 @@
{
- "rust-analyzer.check.command": "clippy",
- "rust-analyzer.checkOnSave": true,
- "rust-analyzer.linkedProjects": [
- ".run/Cargo.toml",
- "mingling_picker/Cargo.toml",
- "mingling_pathf/test/Cargo.toml",
- "mingling_picker/test/Cargo.toml",
- ],
- "rust-analyzer.cargo.features": ["mingling_support"],
+ "rust-analyzer.check.command": "clippy",
+ "rust-analyzer.checkOnSave": true,
+ "rust-analyzer.linkedProjects": [
+ ".run/Cargo.toml",
+ "mingling_pathf/test/Cargo.toml",
+ "arg_picker/Cargo.toml",
+ "arg_picker/test/Cargo.toml"
+ ],
+ "rust-analyzer.cargo.features": ["mingling_support"]
}
diff --git a/.zed/settings.json b/.zed/settings.json
index 12c901e..103cc28 100644
--- a/.zed/settings.json
+++ b/.zed/settings.json
@@ -1,19 +1,19 @@
{
- "lsp": {
- "rust-analyzer": {
- "initialization_options": {
- "checkOnSave": true,
- "check": { "command": "clippy" },
- "linkedProjects": [
- ".run/Cargo.toml",
- "mingling_picker/Cargo.toml",
- "mingling_pathf/test/Cargo.toml",
- "mingling_picker/test/Cargo.toml",
- ],
- "cargo": {
- "features": ["mingling_support"],
- },
- },
- },
- },
+ "lsp": {
+ "rust-analyzer": {
+ "initialization_options": {
+ "checkOnSave": true,
+ "check": { "command": "clippy" },
+ "linkedProjects": [
+ ".run/Cargo.toml",
+ "mingling_pathf/test/Cargo.toml",
+ "arg_picker/Cargo.toml",
+ "arg_picker/test/Cargo.toml"
+ ],
+ "cargo": {
+ "features": ["mingling_support"]
+ }
+ }
+ }
+ }
}
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ab4a170..ac00643 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -64,68 +64,68 @@ None
1. **[`core`]** Added `RenderResult::new()` method for creating a new `RenderResult` with default values (empty text and exit code 0). This provides a more explicit and discoverable constructor compared to `RenderResult::default()`, making it clearer when a fresh result is being created for use with `write!`/`writeln!`.
- ```rust
- let mut result = RenderResult::new();
- writeln!(result, "Hello!").ok();
- result
- ```
+ ```rust
+ let mut result = RenderResult::new();
+ writeln!(result, "Hello!").ok();
+ result
+ ```
- The method is equivalent to `RenderResult::default()` but serves as a more idiomatic entry point for renderer functions.
+ The method is equivalent to `RenderResult::default()` but serves as a more idiomatic entry point for renderer functions.
2. **[`core`]** **[`macros`]** Added `core` and `macros` features to the `mingling` crate, both enabled by default. These features allow selective exclusion of `mingling_core` and `mingling_macros` dependencies respectively.
- - When `core` is **disabled** (`default-features = false, features = ["macros"]`), the `mingling` crate only re-exports proc-macros and macro-related items, without linking `mingling_core`.
- - When `macros` is **disabled** (`default-features = false, features = ["core"]`), the `mingling` crate only provides runtime types and traits without any proc-macro re-exports.
- - When **both are disabled** (`default-features = false`), the `mingling` crate provides a minimal re-export surface.
+ - When `core` is **disabled** (`default-features = false, features = ["macros"]`), the `mingling` crate only re-exports proc-macros and macro-related items, without linking `mingling_core`.
+ - When `macros` is **disabled** (`default-features = false, features = ["core"]`), the `mingling` crate only provides runtime types and traits without any proc-macro re-exports.
+ - When **both are disabled** (`default-features = false`), the `mingling` crate provides a minimal re-export surface.
- This enables downstream projects to fine-tune dependency weight — e.g., a library crate that only uses `mingling_macros` can disable `core` to avoid pulling in unused runtime types.
+ This enables downstream projects to fine-tune dependency weight — e.g., a library crate that only uses `mingling_macros` can disable `core` to avoid pulling in unused runtime types.
3. **[`picker`]** Added the new `picker` system — a **non‑breaking companion** to the existing `parser` feature, not a replacement. The `picker` feature provides a chained argument parsing API and a parsing function library (`parselib`) for analyzing command-line argument structure. Key components:
- - **Chained Argument Parser with `.pick()`** — A chained-call API for declaring and extracting arguments:
+ - **Chained Argument Parser with `.pick()`** — A chained-call API for declaring and extracting arguments:
- ```rust
- use mingling_picker::prelude::*;
+ ```rust
+ use arg_picker::prelude::*;
- let args: Vec<&str> = vec!["--name", "Bob", "--age", "24"];
+ let args: Vec<&str> = vec!["--name", "Bob", "--age", "24"];
- let (name, age) = args
- .pick(&arg![name: String])
- .or(|| "Alice".to_string())
- .pick(&arg![age: i32])
- .or(|| 24)
- .post(|num| num.clamp(0, 120))
- .unwrap();
- ```
+ let (name, age) = args
+ .pick(&arg![name: String])
+ .or(|| "Alice".to_string())
+ .pick(&arg![age: i32])
+ .or(|| 24)
+ .post(|num| num.clamp(0, 120))
+ .unwrap();
+ ```
- - **Pure function library `parselib`** — Provides utility functions for analyzing command-line argument structure:
+ - **Pure function library `parselib`** — Provides utility functions for analyzing command-line argument structure:
- ```rust
- use mingling_picker::parselib::*;
- ```
+ ```rust
+ use arg_picker::parselib::*;
+ ```
- The `picker` system is **additive** — the old `parser` feature remains fully functional and is **not deprecated**. Users may choose either or both systems in the same project. The `picker` feature is available both as the `mingling/picker` feature (enabled by default) and as a standalone `mingling_picker` crate.
+ The `picker` system is **additive** — the old `parser` feature remains fully functional and is **not deprecated**. Users may choose either or both systems in the same project. The `picker` feature is available both as the `mingling/picker` feature (enabled by default) and as a standalone `arg_picker` crate.
- _No migration is required for existing `parser` users — the old API continues to work unchanged._
+ _No migration is required for existing `parser` users — the old API continues to work unchanged._
#### **BREAKING CHANGES** (API CHANGES):
1. **[`macros:renderer`]** **[`macros:help`]** Removed `r_println!` and `r_print!` macros. The `#[renderer]` and `#[help]` macros no longer implicitly inject an internal `RenderResult` variable or provide `r_println!` / `r_print!` macros.
- Renderers and help functions must now explicitly create and return a `RenderResult`:
+ Renderers and help functions must now explicitly create and return a `RenderResult`:
- ```rust
- use mingling::prelude::*;
+ ```rust
+ use mingling::prelude::*;
- #[renderer]
- fn render_greeting(greeting: ResultGreeting) -> RenderResult {
- let mut result = RenderResult::new();
- writeln!(result, "Hello, {}!", *greeting).ok();
- result
- }
- ```
+ #[renderer]
+ fn render_greeting(greeting: ResultGreeting) -> RenderResult {
+ let mut result = RenderResult::new();
+ writeln!(result, "Hello, {}!", *greeting).ok();
+ result
+ }
+ ```
- All examples, docs, and test cases across the repository have been updated to use the new pattern: creating a `RenderResult` with `RenderResult::new()` or `RenderResult::default()`, writing with `write!`/`writeln!` from `std::io::Write`, and returning the result.
+ All examples, docs, and test cases across the repository have been updated to use the new pattern: creating a `RenderResult` with `RenderResult::new()` or `RenderResult::default()`, writing with `write!`/`writeln!` from `std::io::Write`, and returning the result.
---
@@ -160,7 +160,7 @@ None
`"=> EntryList"` would incorrectly match as a substring of `"=> EntryListAlias,"`, causing a false duplicate registration detection.
Now changed to use `find` + trailing character boundary validation, ensuring the character immediately after the match is not an identifier character (letter/digit/underscore).
- Affected scope: Deduplication logic for `#[chain]`, `#[renderer]`, `#[help]`, and `#[completion]` registration.
+ Affected scope: Deduplication logic for `#[chain]`, `#[renderer]`, `#[help]`, and `#[completion]` registration.
#### Optimizations:
@@ -189,36 +189,36 @@ None
1. **[`core`]** - **Added complete unit test coverage**, adding `#[cfg(test)]` test modules for 23 modules in `mingling_core` that previously lacked tests, covering:
- - **Core types** (`any.rs`): `AnyOutput` creation, downcast, type judgment, route routing, restore deserialization; `ChainProcess` type conversion; `NextProcess` formatting
- - **Dispatcher** (`dispatcher.rs`): Conversion of `Dispatchers` from 1~7 tuples, Vec, Box; Deref dereferencing; clone behavior
- - **Node** (`node.rs`): Construction, join, kebab-case conversion, equality comparison, sorting
- - **Global resource** (`global_resource.rs`): `GlobalResource` new, Deref, AsRef; three default implementations of `ResourceMarker`
- - **Lazy resource** (`lazy_resource.rs`): Coverage of all 18+ methods of `LazyRes`, including initialization triggering, get_ref/get_mut/get_clone, into_inner/unwrap, Drop callback, `ResourceMarker` integration
- - **Error types** (`chain/error.rs`, `program/error.rs`): All Display, Error source, From conversions
- - **Configuration structs** (`config.rs`): Default values for `ProgramStdoutSetting`, `ProgramUserContext`; FromStr parsing and Display output of `StructuralRendererSetting` (feature-gated)
- - **Flag system** (`flag.rs`): Added 8 From conversions, Deref, AsRef for `Flag`
- - **String wrapper** (`string_vec.rs`): 6 From conversions, Deref, Into\<Vec\>
- - **Render result** (`render_result.rs`): print/println/clear/is_empty, Write trait, Display, Deref, From conversions
- - **Render error** (`structural/error.rs`): Construction, From, Deref, Into\<String\>
- - **Structural renderer** (`structural.rs`): Rendering in Disable/JSON/YAML/TOML/RON formats (feature-gated)
- - **Completion suggestions** (`suggest.rs`): All construction, access, modification, sorting, and conversion methods for `Suggest` and `SuggestItem`
- - **Shell context** (`shell_ctx.rs`): Added `filling_argument`, `filling_argument_first`, `typing_argument`, `strip_typed_argument`, `get_typed_arguments`
- - **Hook system** (`hook.rs`): `ProgramHook::empty` and all 8 builder methods
- - **Singleton management** (`single_instance.rs`): `ProgramCell` set/get_raw/take/double-set-panic
- - **Program setup** (`setup.rs`): Verification of `with_setup` invocation
- - **Completion detection** (`comp_ctx.rs`): Three scenarios for `is_completing`
- - **Build script** (`builds/comp.rs`): `get_tmpl` for four Shells and Other fallback
+ - **Core types** (`any.rs`): `AnyOutput` creation, downcast, type judgment, route routing, restore deserialization; `ChainProcess` type conversion; `NextProcess` formatting
+ - **Dispatcher** (`dispatcher.rs`): Conversion of `Dispatchers` from 1~7 tuples, Vec, Box; Deref dereferencing; clone behavior
+ - **Node** (`node.rs`): Construction, join, kebab-case conversion, equality comparison, sorting
+ - **Global resource** (`global_resource.rs`): `GlobalResource` new, Deref, AsRef; three default implementations of `ResourceMarker`
+ - **Lazy resource** (`lazy_resource.rs`): Coverage of all 18+ methods of `LazyRes`, including initialization triggering, get_ref/get_mut/get_clone, into_inner/unwrap, Drop callback, `ResourceMarker` integration
+ - **Error types** (`chain/error.rs`, `program/error.rs`): All Display, Error source, From conversions
+ - **Configuration structs** (`config.rs`): Default values for `ProgramStdoutSetting`, `ProgramUserContext`; FromStr parsing and Display output of `StructuralRendererSetting` (feature-gated)
+ - **Flag system** (`flag.rs`): Added 8 From conversions, Deref, AsRef for `Flag`
+ - **String wrapper** (`string_vec.rs`): 6 From conversions, Deref, Into\<Vec\>
+ - **Render result** (`render_result.rs`): print/println/clear/is_empty, Write trait, Display, Deref, From conversions
+ - **Render error** (`structural/error.rs`): Construction, From, Deref, Into\<String\>
+ - **Structural renderer** (`structural.rs`): Rendering in Disable/JSON/YAML/TOML/RON formats (feature-gated)
+ - **Completion suggestions** (`suggest.rs`): All construction, access, modification, sorting, and conversion methods for `Suggest` and `SuggestItem`
+ - **Shell context** (`shell_ctx.rs`): Added `filling_argument`, `filling_argument_first`, `typing_argument`, `strip_typed_argument`, `get_typed_arguments`
+ - **Hook system** (`hook.rs`): `ProgramHook::empty` and all 8 builder methods
+ - **Singleton management** (`single_instance.rs`): `ProgramCell` set/get_raw/take/double-set-panic
+ - **Program setup** (`setup.rs`): Verification of `with_setup` invocation
+ - **Completion detection** (`comp_ctx.rs`): Three scenarios for `is_completing`
+ - **Build script** (`builds/comp.rs`): `get_tmpl` for four Shells and Other fallback
2. **[`core`]** - **Added 6 integration test crates**, testing public APIs under different feature combinations:
- - `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-dispatch-tree`: Basic types with `dispatch_tree` feature
- - `test-all`: Comprehensive testing with all feature combinations (ShellContext, Suggest, ResREPL, StructuralRenderer, Hooks, basic types, etc.)
+ - `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-dispatch-tree`: Basic types with `dispatch_tree` feature
+ - `test-all`: Comprehensive testing with all feature combinations (ShellContext, Suggest, ResREPL, StructuralRenderer, Hooks, basic types, etc.)
- These crates are located in `mingling_core/tests/test-*/`, each marked as an independent workspace via `[workspace]`, isolated from the main workspace.
+ These crates are located in `mingling_core/tests/test-*/`, each marked as an independent workspace via `[workspace]`, isolated from the main workspace.
3. **[`workspace`]** - **Added workspace exclude rules for the 6 test crates in the root `Cargo.toml`**, ensuring that integration test crates are not captured by the workspace's implicit member rules.
@@ -229,33 +229,33 @@ None
2. **[`core:comp`]** Fixed `default_completion` jumping to the next subcommand level on partial input (e.g. typing `b` for `bind` would skip `bind` and directly suggest third-level commands `add`/`ls`/`rm`). Now if the last input word is only a partial match (`starts_with` but not equal), the current-level word is suggested instead of skipping ahead
3. **[`core`]** Replaced `OnceLock<Option<Box<dyn Any>>>` with a custom `ProgramCell` type backed by `UnsafeCell` and `AtomicBool`. The new `ProgramCell` replaces `OnceLock`'s `get_or_init` / `get` / `as_ref` calls with a direct `set` / `get_raw` / `take` API. This change:
- - Eliminates the double indirection (`OnceLock<Option<Box<...>>>` → `UnsafeCell<Option<Box<...>>>`)
- - Allows the program instance to be **taken** (moved out) via an `unsafe fn take()` after execution completes, enabling proper cleanup before `std::process::exit()` in `exec_and_exit`
- - Is paired with corresponding simplifications in `once_exec.rs` and `repl_exec.rs` that switch from `THIS_PROGRAM.get().unwrap().as_ref()` to `THIS_PROGRAM.get_raw().unwrap()`
+ - Eliminates the double indirection (`OnceLock<Option<Box<...>>>` → `UnsafeCell<Option<Box<...>>>`)
+ - Allows the program instance to be **taken** (moved out) via an `unsafe fn take()` after execution completes, enabling proper cleanup before `std::process::exit()` in `exec_and_exit`
+ - Is paired with corresponding simplifications in `once_exec.rs` and `repl_exec.rs` that switch from `THIS_PROGRAM.get().unwrap().as_ref()` to `THIS_PROGRAM.get_raw().unwrap()`
4. **[`macros:dispatcher_clap`]** Added `dispatch_tree` feature integration for `#[dispatcher_clap]`. When the `dispatch_tree` feature is enabled, `#[dispatcher_clap]` will now automatically register the dispatcher and entry in the dispatch tree via `register_dispatcher!`, matching the behavior already present in the `dispatcher!` macro. When the feature is disabled, no additional code is generated.
5. **[`macros`]** The four macros `#[chain]`, `#[renderer]`, `#[help]`, and `#[completion]` now support using fully qualified type paths with `::` (e.g. `crate::EntryFine`) as type inputs. Previously, these macros required types to be bare single-segment idents (e.g. `EntryFine`), rejecting reasonable paths like `crate::EntryFine`. Specific changes:
- - `res_injection::extract_args_info` (shared by `#[chain]` and `#[renderer]`): Removed the single-segment validation for the first parameter type
- - `#[renderer]` / `#[help]`: Removed respective `check_single_segment_type` calls
- - `#[completion]`: Attribute parameter parsing changed from `Ident` to `TypePath`, supporting `#[completion(crate::EntryFine)]`
- - Fixed code generation in `build_chain_arm`, `build_chain_exist_arm`, `build_renderer_entry`, `build_renderer_exist_entry`, `build_general_renderer_entry`, and completion entry: `Self::#variant` match arms now only take the last segment ident of the type path (e.g. `Self::EntryFine`), rather than concatenating the full path directly (which would generate invalid syntax like `Self::crate::EntryFine`), while `downcast::<T>()` and `type Previous = T` still use the full path to ensure correct type resolution
+ - `res_injection::extract_args_info` (shared by `#[chain]` and `#[renderer]`): Removed the single-segment validation for the first parameter type
+ - `#[renderer]` / `#[help]`: Removed respective `check_single_segment_type` calls
+ - `#[completion]`: Attribute parameter parsing changed from `Ident` to `TypePath`, supporting `#[completion(crate::EntryFine)]`
+ - Fixed code generation in `build_chain_arm`, `build_chain_exist_arm`, `build_renderer_entry`, `build_renderer_exist_entry`, `build_general_renderer_entry`, and completion entry: `Self::#variant` match arms now only take the last segment ident of the type path (e.g. `Self::EntryFine`), rather than concatenating the full path directly (which would generate invalid syntax like `Self::crate::EntryFine`), while `downcast::<T>()` and `type Previous = T` still use the full path to ensure correct type resolution
6. **[`macros:register`]** Added compile-time duplicate variant detection for chain, renderer, help, and completion registrations. When two `#[chain]` (or `#[renderer]`, `#[help]`, `#[completion]`) functions register the same type variant, the compiler now emits a clear error at the registration site (e.g. `fn handle_state_prev1(_p: StatePrev1)`) instead of silently producing an unreachable match arm that only manifests as dead code in the generated `do_chain()`/`render()` dispatch.
- Affected registration points:
- - `register_chain` — checks `CHAINS` set for existing entries with the same variant
- - `register_renderer` — checks `RENDERERS` set
- - `help_attr` (via `#[help]`) + `register_help` — checks `HELP_REQUESTS`; `register_help` also serves as a public escape hatch for manual help registration, automatically skipping the duplicate check when the exact same entry was pre-inserted by `#[help]`
- - `completion_attr` (via `#[completion]`) — checks `COMPLETIONS` set
+ Affected registration points:
+ - `register_chain` — checks `CHAINS` set for existing entries with the same variant
+ - `register_renderer` — checks `RENDERERS` set
+ - `help_attr` (via `#[help]`) + `register_help` — checks `HELP_REQUESTS`; `register_help` also serves as a public escape hatch for manual help registration, automatically skipping the duplicate check when the exact same entry was pre-inserted by `#[help]`
+ - `completion_attr` (via `#[completion]`) — checks `COMPLETIONS` set
7. **[`macros:dispatch_tree`]** Fixed the static name generation for dispatch tree nodes to use `snake_case` conversion instead of simple `.` → `_` replacement, and fixed the `__comp` completion dispatcher static name from `__internal_dispatcher___comp` (triple underscore) to `__internal_dispatcher_comp` (double underscore), resolving a mismatch between the name generated by `register_dispatcher!` and the name used in `program_comp_gen`.
8. **[`core`]** Changed the `exec_without_render` and `exec` methods' behavior: when `stdout_setting.render_output` is `false` or the result is empty, the exit code from the result is now returned instead of hardcoded `0`. This ensures that programs which set a non-zero exit code without producing renderable output (e.g., via `ExitCodeSetup` or `ProgramControlUnit::OverrideExitCode`) will exit with the correct code. Specific changes in `once_exec.rs`:
- - `exec()` (async) and `exec_without_render_and_print()` (sync): The `exit_code` is now read from the result before the render check, and returned as the fallback value instead of `0` when output is not printed.
- - This means `ExitCode` / `ProgramControls` overrides are now respected regardless of whether any output is rendered.
+ - `exec()` (async) and `exec_without_render_and_print()` (sync): The `exit_code` is now read from the result before the render check, and returned as the fallback value instead of `0` when output is not printed.
+ - This means `ExitCode` / `ProgramControls` overrides are now respected regardless of whether any output is rendered.
#### Optimizations:
@@ -457,20 +457,20 @@ fn main() {
The pathfinder system consists of:
- **`mingling_pathf` sub-crate** — A standalone crate for build-time source analysis:
- - `module_pathf::analyze()` — Scans the crate's source tree and infers module paths from the directory structure
- - `pattern_analyzer::init()` — Creates a `PatternAnalyzer` registered with all supported Mingling patterns
- - `analyze_and_build_type_mapping()` / `analyze_and_build_type_mapping_for()` — Convenience functions for build scripts
- - **Pattern matchers** — Individual pattern implementations for each Mingling macro:
- - `PackPattern` — Matches `pack!`, `pack_err!`, `pack_structural!`, `pack_err_structural!` invocations
- - `GroupPattern` — Matches `group!` and `group_structural!` invocations
- - `GrouppedDerivePattern` — Matches `#[derive(Groupped)]` and `#[derive(GrouppedSerialize)]`
- - `ChainPattern` — Matches `#[chain]` functions, extracts `__internal_chain_*` names
- - `RendererPattern` — Matches `#[renderer]` functions, extracts `__internal_renderer_*` names
- - `HelpPattern` — Matches `#[help]` functions, extracts `__internal_help_*` names
- - `CompletionPattern` — Matches `#[completion(T)]` functions, extracts `__internal_completion_*` names
- - `DispatcherPattern` — Matches `dispatcher!` invocations, extracts entry type names (supports both explicit and implicit forms)
- - `DispatcherClapPattern` — Matches `#[dispatcher_clap]` structs, extracts struct names
- - `type_mapping_builder` — Assembles the mapping from all analyzed files and writes `MAPPING` and `type_using.rs` output files
+ - `module_pathf::analyze()` — Scans the crate's source tree and infers module paths from the directory structure
+ - `pattern_analyzer::init()` — Creates a `PatternAnalyzer` registered with all supported Mingling patterns
+ - `analyze_and_build_type_mapping()` / `analyze_and_build_type_mapping_for()` — Convenience functions for build scripts
+ - **Pattern matchers** — Individual pattern implementations for each Mingling macro:
+ - `PackPattern` — Matches `pack!`, `pack_err!`, `pack_structural!`, `pack_err_structural!` invocations
+ - `GroupPattern` — Matches `group!` and `group_structural!` invocations
+ - `GrouppedDerivePattern` — Matches `#[derive(Groupped)]` and `#[derive(GrouppedSerialize)]`
+ - `ChainPattern` — Matches `#[chain]` functions, extracts `__internal_chain_*` names
+ - `RendererPattern` — Matches `#[renderer]` functions, extracts `__internal_renderer_*` names
+ - `HelpPattern` — Matches `#[help]` functions, extracts `__internal_help_*` names
+ - `CompletionPattern` — Matches `#[completion(T)]` functions, extracts `__internal_completion_*` names
+ - `DispatcherPattern` — Matches `dispatcher!` invocations, extracts entry type names (supports both explicit and implicit forms)
+ - `DispatcherClapPattern` — Matches `#[dispatcher_clap]` structs, extracts struct names
+ - `type_mapping_builder` — Assembles the mapping from all analyzed files and writes `MAPPING` and `type_using.rs` output files
- **Integration with `gen_program!()`** — When the `pathf` feature is enabled, `gen_program!()` includes the generated `type_using.rs` file via `include!()`, making all type paths available in scope for the generated dispatch code.
@@ -504,29 +504,29 @@ The following explicit syntaxes are **removed**:
1. **[`core`]** **[`structural_renderer`]** Renamed the `general_renderer` feature to `structural_renderer`. All associated types, structs, and APIs have been renamed accordingly:
- - Feature flag: `general_renderer` → `structural_renderer`
- - Setup struct: `GeneralRendererSetup` → `StructuralRendererSetup`
- - Simple setup struct: `GeneralRendererSimpleSetup` → `StructuralRendererSimpleSetup`
- - Renderer type: `GeneralRenderer` → `StructuralRenderer`
- - Setting enum: `GeneralRendererSetting` → `StructuralRendererSetting`
- - Error type: `GeneralRendererSerializeError` → `StructuralRendererSerializeError`
- - Field name: `program.general_renderer_name` → `program.structural_renderer_name`
- - Trait method: `ProgramCollect::general_render()` → `ProgramCollect::structural_render()`
- - Internal module: `mingling_core::renderer::general` → `mingling::renderer::structural`
- - Internal static: `GENERAL_RENDERERS` → `STRUCTURAL_RENDERERS`
- - Feature gate attributes: `#[cfg(feature = "general_renderer")]` → `#[cfg(feature = "structural_renderer")]`
- - Sub-features: `general_renderer_empty` → `structural_renderer_empty`, `general_renderer_full` → `structural_renderer_full`
- - Runtime feature constant: `MINGLING_GENERAL_RENDERER` → `MINGLING_STRUCTURAL_RENDERER` (and similarly for `_EMPTY` and `_FULL`)
- - Derive macro feature gate: `#[cfg(feature = "general_renderer")]` on `#[derive(StructuralData)]` and `#[derive(GrouppedSerialize)]` → `#[cfg(feature = "structural_renderer")]`
- - Example project: `example-general-renderer` renamed to `example-structural-renderer`
- - Test crate: `test-general-renderer` renamed to `test-structural-renderer`
+ - Feature flag: `general_renderer` → `structural_renderer`
+ - Setup struct: `GeneralRendererSetup` → `StructuralRendererSetup`
+ - Simple setup struct: `GeneralRendererSimpleSetup` → `StructuralRendererSimpleSetup`
+ - Renderer type: `GeneralRenderer` → `StructuralRenderer`
+ - Setting enum: `GeneralRendererSetting` → `StructuralRendererSetting`
+ - Error type: `GeneralRendererSerializeError` → `StructuralRendererSerializeError`
+ - Field name: `program.general_renderer_name` → `program.structural_renderer_name`
+ - Trait method: `ProgramCollect::general_render()` → `ProgramCollect::structural_render()`
+ - Internal module: `mingling_core::renderer::general` → `mingling::renderer::structural`
+ - Internal static: `GENERAL_RENDERERS` → `STRUCTURAL_RENDERERS`
+ - Feature gate attributes: `#[cfg(feature = "general_renderer")]` → `#[cfg(feature = "structural_renderer")]`
+ - Sub-features: `general_renderer_empty` → `structural_renderer_empty`, `general_renderer_full` → `structural_renderer_full`
+ - Runtime feature constant: `MINGLING_GENERAL_RENDERER` → `MINGLING_STRUCTURAL_RENDERER` (and similarly for `_EMPTY` and `_FULL`)
+ - Derive macro feature gate: `#[cfg(feature = "general_renderer")]` on `#[derive(StructuralData)]` and `#[derive(GrouppedSerialize)]` → `#[cfg(feature = "structural_renderer")]`
+ - Example project: `example-general-renderer` renamed to `example-structural-renderer`
+ - Test crate: `test-general-renderer` renamed to `test-structural-renderer`
2. **[`core`]** Changed the signature of `ProgramSetup::setup` from `fn setup(&mut self, program: &mut Program<C>) -> S` to `fn setup(self, program: &mut Program<C>)`, consuming `self` instead of taking a mutable reference. Correspondingly, `Program::with_setup` now accepts `S` by value (`&mut self, setup: S`) instead of by mutable reference (`&mut self, setup: &mut S`).
3. **[`core`]** Consolidated resource naming for `ExitCode` and `REPL`:
- - Renamed `ExitCode` to `ResExitCode` and moved `ResREPL` from the `mingling` root to `mingling::res::ResREPL` (the `mingling::ResREPL` re-export is removed).
- - This aligns with the naming convention where resources are prefixed with `Res`.
- - The corresponding setup `ExitCodeSetup` and resource injection remain unchanged.
+ - Renamed `ExitCode` to `ResExitCode` and moved `ResREPL` from the `mingling` root to `mingling::res::ResREPL` (the `mingling::ResREPL` re-export is removed).
+ - This aligns with the naming convention where resources are prefixed with `Res`.
+ - The corresponding setup `ExitCodeSetup` and resource injection remain unchanged.
```rust
// Before
@@ -538,25 +538,25 @@ use mingling::{res::ResExitCode, res::ResREPL};
4. **[`core`]** **[`macros`]** Migrated `to_chain()` and `to_render()` methods from being generated individually per type by `#[derive(Groupped)]` and `pack!` macros, to being provided as default trait methods on the `Groupped` trait itself.
- Previously, each packed or derived type had its own inherent `to_chain()` and `to_render()` methods generated by the macros. Now, these methods are defined on the `Groupped<Group>` trait with default implementations, making them available to all types that implement the trait without redundant code generation.
+ Previously, each packed or derived type had its own inherent `to_chain()` and `to_render()` methods generated by the macros. Now, these methods are defined on the `Groupped<Group>` trait with default implementations, making them available to all types that implement the trait without redundant code generation.
- ```rust
- // Before (generated per type by macros):
- impl MyType {
- pub fn to_chain(self) -> ChainProcess<Group> {
- AnyOutput::new(self).route_chain()
- }
- pub fn to_render(self) -> ChainProcess<Group> {
- AnyOutput::new(self).route_renderer()
- }
- }
+ ```rust
+ // Before (generated per type by macros):
+ impl MyType {
+ pub fn to_chain(self) -> ChainProcess<Group> {
+ AnyOutput::new(self).route_chain()
+ }
+ pub fn to_render(self) -> ChainProcess<Group> {
+ AnyOutput::new(self).route_renderer()
+ }
+ }
- // After (provided by Groupped trait default methods):
- // just ensure Groupped is implemented — to_chain() and to_render()
- // are automatically available
- ```
+ // After (provided by Groupped trait default methods):
+ // just ensure Groupped is implemented — to_chain() and to_render()
+ // are automatically available
+ ```
- Removed the per-type inherent method generation from both `groupped.rs` and `pack.rs` in `mingling_macros`.
+ Removed the per-type inherent method generation from both `groupped.rs` and `pack.rs` in `mingling_macros`.
5. **[`macros`]** Changed the `route!()` macro's error branch from `return e` to `return ::mingling::Groupped::to_chain(e)`, so that the error type no longer needs to be pre-converted to `ChainProcess` via `.to_chain()` or `.to_render()`. The macro now accepts any type implementing `Groupped` in the error position and automatically converts it.
@@ -570,43 +570,43 @@ let value = route!(prev.pick_or_route((), Error::default()).unpack());
6. **[`core`]** **[`hook`]** Refactored the hook system to use structured info types and return `ProgramControls<C>` instead of raw values.
- The hook system has been redesigned for better type safety, extensibility, and control flow management:
+ The hook system has been redesigned for better type safety, extensibility, and control flow management:
- - **All hook callbacks now receive structured info types** (e.g., `&HookPreDispatchInfo`, `&HookPostChainInfo<C>`) instead of raw tuples or bare values. Each hook event has a dedicated info struct with named fields, making hook signatures self-documenting and easier to evolve.
+ - **All hook callbacks now receive structured info types** (e.g., `&HookPreDispatchInfo`, `&HookPostChainInfo<C>`) instead of raw tuples or bare values. Each hook event has a dedicated info struct with named fields, making hook signatures self-documenting and easier to evolve.
- - Hook signatures changed from `fn(...)` to `Box<dyn Fn(&InfoType) -> R>`, with `R: Into<ProgramControls<C>>`. Closures that return `()`are automatically converted to`ProgramControls::Empty`via the`From<()>` impl.
+ - Hook signatures changed from `fn(...)` to `Box<dyn Fn(&InfoType) -> R>`, with `R: Into<ProgramControls<C>>`. Closures that return `()`are automatically converted to`ProgramControls::Empty`via the`From<()>` impl.
- ```rust
- // Before
- .on_begin(|| println!("Program started"))
- .on_pre_dispatch(|args| println!("Dispatching: {args:?}"))
- .on_finish(|| 0) // returns i32 as exit code
+ ```rust
+ // Before
+ .on_begin(|| println!("Program started"))
+ .on_pre_dispatch(|args| println!("Dispatching: {args:?}"))
+ .on_finish(|| 0) // returns i32 as exit code
- // After
- .on_begin::<_, ()>(|_| println!("Program started"))
- .on_pre_dispatch(|info| println!("Dispatching: {}", info.arguments.join(" ")))
- .on_finish(|_| ProgramControlUnit::OverrideExitCode(0))
- ```
+ // After
+ .on_begin::<_, ()>(|_| println!("Program started"))
+ .on_pre_dispatch(|info| println!("Dispatching: {}", info.arguments.join(" ")))
+ .on_finish(|_| ProgramControlUnit::OverrideExitCode(0))
+ ```
- - **Added `ProgramControls<C>` and `ProgramControlUnit<C>`** — a new control flow system that replaces the previous approach where only the `finish` hook could return a value (exit code). Now any hook can issue control instructions:
- - `ProgramControlUnit::OverrideExitCode(i32)` — override the program's exit code
- - `ProgramControlUnit::RouteToChain(AnyOutput<C>)` — route to another chain processor
- - `ProgramControlUnit::RouteToRender(AnyOutput<C>)` — route directly to the renderer
- - `ProgramControlUnit::RouteToHelp(AnyOutput<C>)` — route to help display
+ - **Added `ProgramControls<C>` and `ProgramControlUnit<C>`** — a new control flow system that replaces the previous approach where only the `finish` hook could return a value (exit code). Now any hook can issue control instructions:
+ - `ProgramControlUnit::OverrideExitCode(i32)` — override the program's exit code
+ - `ProgramControlUnit::RouteToChain(AnyOutput<C>)` — route to another chain processor
+ - `ProgramControlUnit::RouteToRender(AnyOutput<C>)` — route directly to the renderer
+ - `ProgramControlUnit::RouteToHelp(AnyOutput<C>)` — route to help display
- - **Added `handle_program_control` function** in `exec.rs` that processes `ProgramControls` returned by hooks, updating the current execution state (exit code, current `AnyOutput`) or triggering early returns (e.g., routing to render/help).
+ - **Added `handle_program_control` function** in `exec.rs` that processes `ProgramControls` returned by hooks, updating the current execution state (exit code, current `AnyOutput`) or triggering early returns (e.g., routing to render/help).
- - **`ExitCodeSetup` updated** — its `on_finish` hook now returns `ProgramControlUnit::OverrideExitCode(this.exit_code)` instead of just `this.exit_code`.
+ - **`ExitCodeSetup` updated** — its `on_finish` hook now returns `ProgramControlUnit::OverrideExitCode(this.exit_code)` instead of just `this.exit_code`.
- - **`HookPostReadlineInfo` now wraps `line: &mut String`** — the `repl_post_readline` hook receives a structured info object instead of a raw `&mut String`.
+ - **`HookPostReadlineInfo` now wraps `line: &mut String`** — the `repl_post_readline` hook receives a structured info object instead of a raw `&mut String`.
- - **`HookOnReceiveResultInfo` now wraps `result: &RenderResult`** — the `repl_on_receive_result` hook receives the result through an info struct with a `.result` field instead of directly.
+ - **`HookOnReceiveResultInfo` now wraps `result: &RenderResult`** — the `repl_on_receive_result` hook receives the result through an info struct with a `.result` field instead of directly.
- - **`hook` module made public** — moved from `#[doc(hidden)]` to a documented public module (`pub mod hook`), along with all associated info types and control unit types.
+ - **`hook` module made public** — moved from `#[doc(hidden)]` to a documented public module (`pub mod hook`), along with all associated info types and control unit types.
- - **Added `dispatch_args_trie` default method** on `ProgramCollect` (behind `#[cfg(not(feature = "dispatch_tree"))]`) that calls `unreachable!()` by default, avoiding `#[cfg]` gymnastics in `exec.rs`.
+ - **Added `dispatch_args_trie` default method** on `ProgramCollect` (behind `#[cfg(not(feature = "dispatch_tree"))]`) that calls `unreachable!()` by default, avoiding `#[cfg]` gymnastics in `exec.rs`.
- - **Examples and internal callers updated** throughout the codebase to use the new hook API patterns.
+ - **Examples and internal callers updated** throughout the codebase to use the new hook API patterns.
7. **[`core`]** **[`structural_renderer`]** Added the `pack_err_structural!`, `pack_structural!`, and `group_structural!` macros for creating types that support structured output (JSON/YAML/TOML/RON). These are like `pack_err!`, `pack!`, and `group!` respectively, but also mark the type with the `StructuralData` trait, enabling the `StructuralRenderer` to serialize them.
@@ -634,8 +634,8 @@ When the `structural_renderer` feature is enabled, `ResultEmpty` also derives `S
#### Fixes:
1. **[`macros:dispatcher_clap`]** Fixed the issue where clap error messages (`DisplayHelp` and parse errors from `try_parse_from`) could not output ANSI
- - For error paths, use `e.render().ansi()` instead of `e.to_string()` to prevent ANSI codes from being stripped by `strip_str` in `StyledStr::Display`
- - For help info paths, use with `BasicProgramSetup`, output ANSI-colored help content through the mingling framework's `render_help` flow
+ - For error paths, use `e.render().ansi()` instead of `e.to_string()` to prevent ANSI codes from being stripped by `strip_str` in `StyledStr::Display`
+ - For help info paths, use with `BasicProgramSetup`, output ANSI-colored help content through the mingling framework's `render_help` flow
#### Optimizations:
@@ -675,8 +675,8 @@ fn handle_path_pick(prev: PathPick) {
```
3. **[`macros`]** Extended the `#[renderer]` attribute to support custom return types. Previously, `#[renderer]` functions could only return `()`, and the generated helper function always returned `RenderResult`. Now:
- - **`fn foo(x: T)` / `fn foo(x: T) -> ()`** → The generated helper function returns `()`. If the internal `RenderResult` (`dummy_r`) is non-empty, it is automatically printed to stdout.
- - **`fn foo(x: T) -> U`** → The generated helper function returns `U`. The internal `RenderResult` is converted via `dummy_r.into()`, and no automatic printing occurs.
+ - **`fn foo(x: T)` / `fn foo(x: T) -> ()`** → The generated helper function returns `()`. If the internal `RenderResult` (`dummy_r`) is non-empty, it is automatically printed to stdout.
+ - **`fn foo(x: T) -> U`** → The generated helper function returns `U`. The internal `RenderResult` is converted via `dummy_r.into()`, and no automatic printing occurs.
4. **[`macros`]** Resource injection is now shared between `#[chain]` and `#[renderer]`.
Extracted the common resource injection infrastructure (`ResourceInjection`, `extract_args_info`, `generate_immut_resource_bindings`, `wrap_body_with_mut_resources`) from `chain.rs` into a new `res_injection.rs` module. Both `#[chain]` and `#[renderer]` now reuse the same logic.
@@ -823,10 +823,10 @@ None
1. **[`core`]** The core library no longer depends on `thiserror`
2. **[`mingling`]** Split the monolithic `general_renderer` feature into separate format-specific features:
- - `general_renderer` now only includes core serialization support without any specific format
- - `general_renderer_full` bundles all available serialization formats
- - Individual format features: `json_serde_fmt`, `yaml_serde_fmt`, `toml_serde_fmt`, `ron_serde_fmt`
- - A meta feature `all_serde_fmt` enables all format features at once
+ - `general_renderer` now only includes core serialization support without any specific format
+ - `general_renderer_full` bundles all available serialization formats
+ - Individual format features: `json_serde_fmt`, `yaml_serde_fmt`, `toml_serde_fmt`, `ron_serde_fmt`
+ - A meta feature `all_serde_fmt` enables all format features at once
#### Features:
@@ -946,9 +946,9 @@ fn my_chain(prev: Prev) -> Next {
1. **[`core`]** The signature of `exec` has been changed to `exec(self) -> i32` (previously was `exec(self)`)
2. **[`macros`]** All proc macros that accept a program/group name parameter (e.g. `pack!`, `dispatcher!`, `#[chain]`, `#[program_setup]`, `#[dispatcher_clap]`, `#[derive(Groupped)]`) now parse the name as a `syn::Path` instead of a bare `Ident`. This means:
- - You can now use paths like `crate::MyProgram` or `my_crate::MyProgram` in addition to plain `MyProgram`.
- - The default program name `ThisProgram` is no longer re-exported or required as an import — generated code references `crate::ThisProgram` directly.
- - If you previously imported `ThisProgram` from `crate` only for macro use, that import is no longer needed and can be removed.
+ - You can now use paths like `crate::MyProgram` or `my_crate::MyProgram` in addition to plain `MyProgram`.
+ - The default program name `ThisProgram` is no longer re-exported or required as an import — generated code references `crate::ThisProgram` directly.
+ - If you previously imported `ThisProgram` from `crate` only for macro use, that import is no longer needed and can be removed.
```rust
use crate::ThisProgram; // Can be removed if not used directly
@@ -1125,9 +1125,9 @@ gen_program!();
```
6. **[`picker`]** Simplified `Picker` logic:
- - `Picker` no longer requires the generic parameter `<G>` by default; it only needs it when using `pick_or_route` or `after_or_route`
+ - `Picker` no longer requires the generic parameter `<G>` by default; it only needs it when using `pick_or_route` or `after_or_route`
- - Additionally, if no `or_route` operations are used, the `unpack_directly` function is no longer available; `unpack` will directly extract the inner value
+ - Additionally, if no `or_route` operations are used, the `unpack_directly` function is no longer available; `unpack` will directly extract the inner value
```rust
// Before
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index b10e96d..e729295 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -6,22 +6,22 @@ Before contributing, we recommend reading [README](README.md) to get an overview
## 1. Project Structure 📦
-| Category | Path/Name | Description |
-| --------------------------- | ------------------------- | ------------------------------------------------------------------ |
-| **Entry crate** | `mingling/` | Project entry point |
-| **Core library** | `mingling_core/` | Imported as an external dependency |
-| **Macro library** | `mingling_macros/` | Imported as an external dependency |
-| **Mingling Pathfinder** | `mingling_pathf/` | Build-time module path resolution for types |
-| **Mingling Picker2** | `mingling_picker/` | Mingling Arguments Parser |
-| **Mingling Picker2 Macros** | `mingling_picker_macros/` | Mingling Arguments Parser Macros |
-| **Scaffolding tool** | `mling/` | Scaffolding tool `mingling-cli` |
-| **Examples** | `examples/` | To add expected output tests, modify `examples/test-examples.toml` |
-| **Documents** | `docs/` | All documents |
-| **Dev Documents** | `docs/dev/` | Internal documents |
-| **Resources** | `docs/res/` | All resources |
-| **Development tools** | `.run/src/bin` | Contains scripts and Rust tools |
-| **CI** | `.run/src/bin/ci.rs` | Can be invoked directly via `cargo ci` |
-| **Temporary files** | `.temp/` | Ignored by `.gitignore` |
+| Category | Path/Name | Description |
+| --------------------------- | -------------------- | ------------------------------------------------------------------ |
+| **Entry crate** | `mingling/` | Project entry point |
+| **Core library** | `mingling_core/` | Imported as an external dependency |
+| **Macro library** | `mingling_macros/` | Imported as an external dependency |
+| **Mingling Pathfinder** | `mingling_pathf/` | Build-time module path resolution for types |
+| **Mingling Picker2** | `arg_picker/` | Mingling Arguments Parser |
+| **Mingling Picker2 Macros** | `arg_picker_macros/` | Mingling Arguments Parser Macros |
+| **Scaffolding tool** | `mling/` | Scaffolding tool `mingling-cli` |
+| **Examples** | `examples/` | To add expected output tests, modify `examples/test-examples.toml` |
+| **Documents** | `docs/` | All documents |
+| **Dev Documents** | `docs/dev/` | Internal documents |
+| **Resources** | `docs/res/` | All resources |
+| **Development tools** | `.run/src/bin` | Contains scripts and Rust tools |
+| **CI** | `.run/src/bin/ci.rs` | Can be invoked directly via `cargo ci` |
+| **Temporary files** | `.temp/` | Ignored by `.gitignore` |
## 2. How to Contribute
@@ -113,28 +113,28 @@ No strict requirements here — just modify the relevant `*.html` files. Preview
## 3. Submission Guide 🖊
1. **Pull Request**
- - Submit a GitHub Pull Request and @Reviewer **[Weicao-CatilGrass](https://github.com/Weicao-CatilGrass)** for review
- - Or send patches to **catil_grass@qq.com**
+ - Submit a GitHub Pull Request and @Reviewer **[Weicao-CatilGrass](https://github.com/Weicao-CatilGrass)** for review
+ - Or send patches to **catil_grass@qq.com**
2. **Commit Messages**
- - Clearly and concisely describe the changes, no stringent requirements
- - Provide more detail for complex changes, keep it brief for simple changes
- - But: if you use [Conventional Commits](https://www.conventionalcommits.org/), it would make me even happier :)
+ - Clearly and concisely describe the changes, no stringent requirements
+ - Provide more detail for complex changes, keep it brief for simple changes
+ - But: if you use [Conventional Commits](https://www.conventionalcommits.org/), it would make me even happier :)
3. **CHANGELOG**
- - If the submission includes functional changes or fixes, **the PR must include modifications to CHANGELOG.md** to describe the changes
- - For minor changes like typo fixes, **CHANGELOG.md modification is not required**, and we will merge faster
+ - If the submission includes functional changes or fixes, **the PR must include modifications to CHANGELOG.md** to describe the changes
+ - For minor changes like typo fixes, **CHANGELOG.md modification is not required**, and we will merge faster
4. **Multi-commit PR**
- - A PR can contain multiple commits
- - However, at least one commit must modify CHANGELOG.md
+ - A PR can contain multiple commits
+ - However, at least one commit must modify CHANGELOG.md
5. **Review**
- - After submission, please notify [Weicao-CatilGrass](https://github.com/Weicao-CatilGrass) for review — this is the most efficient way to get feedback
+ - After submission, please notify [Weicao-CatilGrass](https://github.com/Weicao-CatilGrass) for review — this is the most efficient way to get feedback
6. **Binary Resources**
- - For binary resource files (images, etc.), please be cautious about adding them to avoid repository bloat
+ - For binary resource files (images, etc.), please be cautious about adding them to avoid repository bloat
## 4. Documentation Contribution 📕
diff --git a/Cargo.lock b/Cargo.lock
index a283e0f..4c0682e 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -71,6 +71,24 @@ dependencies = [
]
[[package]]
+name = "arg-picker"
+version = "0.1.0"
+dependencies = [
+ "arg-picker-macros",
+ "just_fmt 0.2.0",
+ "mingling_core",
+]
+
+[[package]]
+name = "arg-picker-macros"
+version = "0.1.0"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
name = "autocfg"
version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -409,10 +427,10 @@ checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
name = "mingling"
version = "0.3.0"
dependencies = [
+ "arg-picker",
"mingling",
"mingling_core",
"mingling_macros",
- "mingling_picker",
"serde",
"size",
"tokio",
@@ -468,24 +486,6 @@ dependencies = [
]
[[package]]
-name = "mingling_picker"
-version = "0.3.0"
-dependencies = [
- "just_fmt 0.2.0",
- "mingling_core",
- "mingling_picker_macros",
-]
-
-[[package]]
-name = "mingling_picker_macros"
-version = "0.3.0"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
name = "mio"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index 90989fc..99523c7 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -10,8 +10,8 @@ members = [
"mingling_pathf",
# Picker2
- "mingling_picker",
- "mingling_picker_macros",
+ "arg_picker",
+ "arg_picker_macros",
# Scaffolding tool
"mling"
@@ -36,8 +36,9 @@ exclude = [
mingling_core = { path = "mingling_core", default-features = false }
mingling_macros = { path = "mingling_macros", default-features = false }
mingling_pathf = { path = "mingling_pathf", default-features = false }
-mingling_picker = { path = "mingling_picker", default-features = false }
-mingling_picker_macros = { path = "mingling_picker_macros", default-features = false }
+
+arg-picker = { path = "arg_picker", default-features = false }
+arg-picker-macros = { path = "arg_picker_macros", default-features = false }
just_fmt = "0.2.0"
just_template = "0.2.0"
diff --git a/arg_picker/Cargo.toml b/arg_picker/Cargo.toml
new file mode 100644
index 0000000..f7672c1
--- /dev/null
+++ b/arg_picker/Cargo.toml
@@ -0,0 +1,17 @@
+[package]
+name = "arg-picker"
+version = "0.1.0"
+edition = "2024"
+license = "MIT OR Apache-2.0"
+repository = "https://github.com/mingling-rs/mingling/tree/main/arg-picker"
+authors = ["Weicao-CatilGrass"]
+readme = "README.md"
+description = "A lightweight, type-safe CLI argument parser"
+
+[features]
+mingling_support = ["dep:mingling_core", "arg-picker-macros/mingling_support"]
+
+[dependencies]
+mingling_core = { workspace = true, optional = true }
+arg-picker-macros.workspace = true
+just_fmt.workspace = true
diff --git a/mingling_picker/README.md b/arg_picker/README.md
index db67825..14051f3 100644
--- a/mingling_picker/README.md
+++ b/arg_picker/README.md
@@ -1,4 +1,4 @@
-# Mingling Picker
+# Argument Picker
A command-line argument parser for [Mingling](https://github.com/mingling-rs/mingling), enabled by the `mingling/picker` feature.
@@ -10,11 +10,11 @@ features = [
]
```
-Of course, you can also use it as a standalone crate by replacing `mingling::picker` with `mingling_picker`:
+Of course, you can also use it as a standalone crate by replacing `mingling::picker` with `arg_picker`:
```toml
[dependencies]
-mingling_picker = "0.3.0"
+arg-picker = "0.1.0"
```
## Chained Argument Parser
@@ -22,7 +22,7 @@ mingling_picker = "0.3.0"
Provides a clean chained-call API for declaring arguments to parse:
```rust
-use mingling_picker::prelude::*;
+use arg_picker::prelude::*;
let args: Vec<&str> = vec!["--name", "Bob", "--age", "24"];
@@ -43,5 +43,5 @@ assert_eq!(age, 24);
Provides a pure function library `parselib` for analyzing the structure of command-line arguments.
```rust
-use mingling_picker::parselib::*;
+use arg_picker::parselib::*;
```
diff --git a/mingling_picker/src/arg.rs b/arg_picker/src/arg.rs
index 78ad539..78ad539 100644
--- a/mingling_picker/src/arg.rs
+++ b/arg_picker/src/arg.rs
diff --git a/mingling_picker/src/builtin.rs b/arg_picker/src/builtin.rs
index e855b08..e855b08 100644
--- a/mingling_picker/src/builtin.rs
+++ b/arg_picker/src/builtin.rs
diff --git a/mingling_picker/src/builtin/pick_bool.rs b/arg_picker/src/builtin/pick_bool.rs
index ccc4424..ccc4424 100644
--- a/mingling_picker/src/builtin/pick_bool.rs
+++ b/arg_picker/src/builtin/pick_bool.rs
diff --git a/mingling_picker/src/builtin/pick_flag.rs b/arg_picker/src/builtin/pick_flag.rs
index b642a9a..b642a9a 100644
--- a/mingling_picker/src/builtin/pick_flag.rs
+++ b/arg_picker/src/builtin/pick_flag.rs
diff --git a/mingling_picker/src/builtin/pick_numbers.rs b/arg_picker/src/builtin/pick_numbers.rs
index a5ab0a9..a5ab0a9 100644
--- a/mingling_picker/src/builtin/pick_numbers.rs
+++ b/arg_picker/src/builtin/pick_numbers.rs
diff --git a/mingling_picker/src/builtin/pick_string.rs b/arg_picker/src/builtin/pick_string.rs
index c96f667..c96f667 100644
--- a/mingling_picker/src/builtin/pick_string.rs
+++ b/arg_picker/src/builtin/pick_string.rs
diff --git a/mingling_picker/src/corebind.rs b/arg_picker/src/corebind.rs
index 3581871..3581871 100644
--- a/mingling_picker/src/corebind.rs
+++ b/arg_picker/src/corebind.rs
diff --git a/mingling_picker/src/corebind/entry_picker.rs b/arg_picker/src/corebind/entry_picker.rs
index 69bc4d8..69bc4d8 100644
--- a/mingling_picker/src/corebind/entry_picker.rs
+++ b/arg_picker/src/corebind/entry_picker.rs
diff --git a/mingling_picker/src/infos.rs b/arg_picker/src/infos.rs
index d2a0fce..074539a 100644
--- a/mingling_picker/src/infos.rs
+++ b/arg_picker/src/infos.rs
@@ -51,7 +51,7 @@ impl<Type> PickerArgResult<Type> {
/// # Examples
///
/// ```
- /// use mingling_picker::PickerArgResult;
+ /// use arg_picker::PickerArgResult;
///
/// let result: PickerArgResult<i32> = PickerArgResult::Parsed(42);
/// assert!(result.is_parsed());
@@ -70,7 +70,7 @@ impl<Type> PickerArgResult<Type> {
/// # Examples
///
/// ```
- /// use mingling_picker::PickerArgResult;
+ /// use arg_picker::PickerArgResult;
///
/// let result: PickerArgResult<i32> = PickerArgResult::Parsed(42);
/// assert!(result.is_found());
@@ -87,7 +87,7 @@ impl<Type> PickerArgResult<Type> {
/// # Examples
///
/// ```
- /// use mingling_picker::PickerArgResult;
+ /// use arg_picker::PickerArgResult;
///
/// let result: PickerArgResult<i32> = PickerArgResult::Unparsed;
/// assert!(result.is_err());
@@ -104,7 +104,7 @@ impl<Type> PickerArgResult<Type> {
/// # Examples
///
/// ```
- /// use mingling_picker::PickerArgResult;
+ /// use arg_picker::PickerArgResult;
///
/// let result: PickerArgResult<i32> = PickerArgResult::Parsed(42);
/// assert_eq!(result.parsed(), Some(&42));
@@ -128,7 +128,7 @@ impl<Type> PickerArgResult<Type> {
/// # Examples
///
/// ```should_panic
- /// use mingling_picker::PickerArgResult;
+ /// use arg_picker::PickerArgResult;
///
/// let result: PickerArgResult<i32> = PickerArgResult::NotFound;
/// result.expect("expected a parsed value");
@@ -148,14 +148,14 @@ impl<Type> PickerArgResult<Type> {
/// # Examples
///
/// ```
- /// use mingling_picker::PickerArgResult;
+ /// use arg_picker::PickerArgResult;
///
/// let result: PickerArgResult<i32> = PickerArgResult::Parsed(42);
/// assert_eq!(result.unwrap(), 42);
/// ```
///
/// ```should_panic
- /// use mingling_picker::PickerArgResult;
+ /// use arg_picker::PickerArgResult;
///
/// let result: PickerArgResult<i32> = PickerArgResult::NotFound;
/// result.unwrap();
@@ -177,7 +177,7 @@ impl<Type> PickerArgResult<Type> {
/// # Examples
///
/// ```
- /// use mingling_picker::PickerArgResult;
+ /// use arg_picker::PickerArgResult;
///
/// let result: PickerArgResult<i32> = PickerArgResult::Parsed(42);
/// assert_eq!(result.unwrap_or(0), 42);
@@ -197,7 +197,7 @@ impl<Type> PickerArgResult<Type> {
/// # Examples
///
/// ```
- /// use mingling_picker::PickerArgResult;
+ /// use arg_picker::PickerArgResult;
///
/// let result: PickerArgResult<i32> = PickerArgResult::Parsed(42);
/// assert_eq!(result.unwrap_or_else(|| 0), 42);
@@ -217,7 +217,7 @@ impl<Type> PickerArgResult<Type> {
/// # Examples
///
/// ```
- /// use mingling_picker::PickerArgResult;
+ /// use arg_picker::PickerArgResult;
///
/// let result: PickerArgResult<i32> = PickerArgResult::Parsed(42);
/// assert_eq!(result.unwrap_or_default(), 42);
@@ -242,7 +242,7 @@ impl<Type> PickerArgResult<Type> {
/// # Examples
///
/// ```
- /// use mingling_picker::PickerArgResult;
+ /// use arg_picker::PickerArgResult;
///
/// let result: PickerArgResult<i32> = PickerArgResult::Parsed(42);
/// assert_eq!(result.to_option(), Some(42));
diff --git a/mingling_picker/src/lib.rs b/arg_picker/src/lib.rs
index deb266e..21a0d35 100644
--- a/mingling_picker/src/lib.rs
+++ b/arg_picker/src/lib.rs
@@ -26,7 +26,7 @@ pub mod value;
/// This module is intended to be imported with a wildcard import:
///
/// ```
-/// use mingling_picker::prelude::*;
+/// use arg_picker::prelude::*;
/// ```
pub mod prelude {
pub use crate::macros::arg;
@@ -38,9 +38,9 @@ pub mod prelude {
pub use crate::corebind::EntryPicker;
}
-/// Re-export of the `mingling_picker_macros` crate
+/// Re-export of the `arg_picker_macros` crate
pub mod macros {
- pub use mingling_picker_macros::arg;
+ pub use arg_picker_macros::arg;
}
/// Provides the types necessary for implementing the `Pickable` trait
diff --git a/mingling_picker/src/parselib.rs b/arg_picker/src/parselib.rs
index 7fbd606..7fbd606 100644
--- a/mingling_picker/src/parselib.rs
+++ b/arg_picker/src/parselib.rs
diff --git a/mingling_picker/src/parselib/arg_matcher.rs b/arg_picker/src/parselib/arg_matcher.rs
index 38bb9cc..38bb9cc 100644
--- a/mingling_picker/src/parselib/arg_matcher.rs
+++ b/arg_picker/src/parselib/arg_matcher.rs
diff --git a/mingling_picker/src/parselib/flag_matcher.rs b/arg_picker/src/parselib/flag_matcher.rs
index e93d35a..e93d35a 100644
--- a/mingling_picker/src/parselib/flag_matcher.rs
+++ b/arg_picker/src/parselib/flag_matcher.rs
diff --git a/mingling_picker/src/parselib/multi_arg_matcher.rs b/arg_picker/src/parselib/multi_arg_matcher.rs
index 748b1be..748b1be 100644
--- a/mingling_picker/src/parselib/multi_arg_matcher.rs
+++ b/arg_picker/src/parselib/multi_arg_matcher.rs
diff --git a/mingling_picker/src/parselib/pos_matcher.rs b/arg_picker/src/parselib/pos_matcher.rs
index 279e01e..279e01e 100644
--- a/mingling_picker/src/parselib/pos_matcher.rs
+++ b/arg_picker/src/parselib/pos_matcher.rs
diff --git a/mingling_picker/src/parselib/single_matcher.rs b/arg_picker/src/parselib/single_matcher.rs
index 25c4741..25c4741 100644
--- a/mingling_picker/src/parselib/single_matcher.rs
+++ b/arg_picker/src/parselib/single_matcher.rs
diff --git a/mingling_picker/src/parselib/style.rs b/arg_picker/src/parselib/style.rs
index dd01125..36ba8f0 100644
--- a/mingling_picker/src/parselib/style.rs
+++ b/arg_picker/src/parselib/style.rs
@@ -40,7 +40,7 @@ impl<'a> ParserStyle<'a> {
/// # Examples
///
/// ```
- /// # use mingling_picker::parselib::{ParserStyle, FlagStr, UNIX_STYLE};
+ /// # use arg_picker::parselib::{ParserStyle, FlagStr, UNIX_STYLE};
/// let style = &UNIX_STYLE;
///
/// assert_eq!(style.flag_string('v'), "-v");
@@ -76,7 +76,7 @@ impl<'a> ParserStyle<'a> {
/// # Examples
///
/// ```
-/// use mingling_picker::parselib::FlagStr;
+/// use arg_picker::parselib::FlagStr;
///
/// let short: FlagStr = 'v'.into();
/// let long: FlagStr = "verbose".into();
@@ -117,8 +117,8 @@ impl<'a> From<&'a String> for FlagStr<'a> {
/// # Examples
///
/// ```
-/// # use mingling_picker::IntoPicker;
-/// use mingling_picker::parselib::ParserStyleNamingCase;
+/// # use arg_picker::IntoPicker;
+/// use arg_picker::parselib::ParserStyleNamingCase;
///
/// let case = ParserStyleNamingCase::Kebab;
/// assert_eq!(
@@ -174,7 +174,7 @@ impl ParserStyleNamingCase {
/// # Examples
///
/// ```
- /// use mingling_picker::parselib::ParserStyleNamingCase;
+ /// use arg_picker::parselib::ParserStyleNamingCase;
///
/// let camel = ParserStyleNamingCase::Camel;
/// assert_eq!(camel.convert("brew_coffee".to_string()), "brewCoffee");
diff --git a/mingling_picker/src/parselib/utils.rs b/arg_picker/src/parselib/utils.rs
index 47c5b55..47c5b55 100644
--- a/mingling_picker/src/parselib/utils.rs
+++ b/arg_picker/src/parselib/utils.rs
diff --git a/mingling_picker/src/pickable.rs b/arg_picker/src/pickable.rs
index 758ae9a..758ae9a 100644
--- a/mingling_picker/src/pickable.rs
+++ b/arg_picker/src/pickable.rs
diff --git a/mingling_picker/src/pickable/multi_pickable.rs b/arg_picker/src/pickable/multi_pickable.rs
index 84a8068..84a8068 100644
--- a/mingling_picker/src/pickable/multi_pickable.rs
+++ b/arg_picker/src/pickable/multi_pickable.rs
diff --git a/mingling_picker/src/pickable/single_pickable.rs b/arg_picker/src/pickable/single_pickable.rs
index 8a5b3e6..8a5b3e6 100644
--- a/mingling_picker/src/pickable/single_pickable.rs
+++ b/arg_picker/src/pickable/single_pickable.rs
diff --git a/mingling_picker/src/picker.rs b/arg_picker/src/picker.rs
index 7cf1525..ecab648 100644
--- a/mingling_picker/src/picker.rs
+++ b/arg_picker/src/picker.rs
@@ -320,7 +320,7 @@ pub trait IntoPicker<'a> {
/// # Examples
///
/// ```
- /// use mingling_picker::{IntoPicker, Picker};
+ /// use arg_picker::{IntoPicker, Picker};
///
/// let args: Picker = (&["hello", "world"][..]).to_picker();
/// assert_eq!(args.len(), 2);
diff --git a/mingling_picker/src/picker/parse.rs b/arg_picker/src/picker/parse.rs
index 698baac..366028b 100644
--- a/mingling_picker/src/picker/parse.rs
+++ b/arg_picker/src/picker/parse.rs
@@ -11,7 +11,7 @@
#![allow(clippy::type_complexity)]
use crate::{Pickable, PickerArgAttr, PickerArgInfo, PickerArgResult, PickerArgs, TagPhaseContext};
-use mingling_picker_macros::internal_repeat;
+use arg_picker_macros::internal_repeat;
internal_repeat!(1..=32 => {
use crate::PickerPattern$;
diff --git a/mingling_picker/src/picker/patterns.rs b/arg_picker/src/picker/patterns.rs
index 78ae2b0..5806605 100644
--- a/mingling_picker/src/picker/patterns.rs
+++ b/arg_picker/src/picker/patterns.rs
@@ -1,4 +1,4 @@
-use mingling_picker_macros::internal_repeat;
+use arg_picker_macros::internal_repeat;
use crate::{Pickable, PickerArg, PickerArgResult, PickerArgs};
diff --git a/mingling_picker/src/picker/result.rs b/arg_picker/src/picker/result.rs
index 9cd78ae..83ca2cd 100644
--- a/mingling_picker/src/picker/result.rs
+++ b/arg_picker/src/picker/result.rs
@@ -1,6 +1,6 @@
#![allow(clippy::type_complexity)] // Aha, Type Gymnastics!
-use mingling_picker_macros::internal_repeat;
+use arg_picker_macros::internal_repeat;
internal_repeat!(1..=32 => {
#[doc(hidden)]
diff --git a/mingling_picker/src/value.rs b/arg_picker/src/value.rs
index 995aa00..995aa00 100644
--- a/mingling_picker/src/value.rs
+++ b/arg_picker/src/value.rs
diff --git a/mingling_picker/src/value/flag.rs b/arg_picker/src/value/flag.rs
index ee0d6ee..c0673bd 100644
--- a/mingling_picker/src/value/flag.rs
+++ b/arg_picker/src/value/flag.rs
@@ -26,7 +26,7 @@ use std::{
/// directly in boolean contexts:
///
/// ```
-/// # use mingling_picker::value::Flag;
+/// # use arg_picker::value::Flag;
/// let flag = Flag::Active;
/// if *flag { /* runs */ }
/// ```
@@ -72,7 +72,7 @@ impl Flag {
/// # Examples
///
/// ```
- /// # use mingling_picker::value::Flag;
+ /// # use arg_picker::value::Flag;
/// assert!(Flag::Active.bool());
/// assert!(!Flag::Inactive.bool());
/// ```
@@ -116,7 +116,7 @@ impl From<Flag> for bool {
/// # Examples
///
/// ```
-/// # use mingling_picker::value::Flag;
+/// # use arg_picker::value::Flag;
/// let flag = Flag::Active;
/// if *flag {
/// println!("flag is set");
diff --git a/mingling_picker/src/value/vec_until.rs b/arg_picker/src/value/vec_until.rs
index 1b79641..1b79641 100644
--- a/mingling_picker/src/value/vec_until.rs
+++ b/arg_picker/src/value/vec_until.rs
diff --git a/mingling_picker/test/Cargo.lock b/arg_picker/test/Cargo.lock
index 0fef84b..5d44838 100644
--- a/mingling_picker/test/Cargo.lock
+++ b/arg_picker/test/Cargo.lock
@@ -3,22 +3,16 @@
version = 4
[[package]]
-name = "just_fmt"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6170dccbc3ea15dfb7f2da964097f814aba1dd8f746d4ffc56f33245c38e6d96"
-
-[[package]]
-name = "mingling_picker"
-version = "0.3.0"
+name = "arg-picker"
+version = "0.1.0"
dependencies = [
+ "arg-picker-macros",
"just_fmt",
- "mingling_picker_macros",
]
[[package]]
-name = "mingling_picker_macros"
-version = "0.3.0"
+name = "arg-picker-macros"
+version = "0.1.0"
dependencies = [
"proc-macro2",
"quote",
@@ -26,6 +20,19 @@ dependencies = [
]
[[package]]
+name = "arg-picker-test"
+version = "0.1.0"
+dependencies = [
+ "arg-picker",
+]
+
+[[package]]
+name = "just_fmt"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6170dccbc3ea15dfb7f2da964097f814aba1dd8f746d4ffc56f33245c38e6d96"
+
+[[package]]
name = "proc-macro2"
version = "1.0.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -55,13 +62,6 @@ dependencies = [
]
[[package]]
-name = "test-mingling-picker"
-version = "0.1.0"
-dependencies = [
- "mingling_picker",
-]
-
-[[package]]
name = "unicode-ident"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/mingling_picker/test/Cargo.toml b/arg_picker/test/Cargo.toml
index 127546c..2c366c7 100644
--- a/mingling_picker/test/Cargo.toml
+++ b/arg_picker/test/Cargo.toml
@@ -1,9 +1,9 @@
[package]
-name = "test-mingling-picker"
+name = "arg-picker-test"
version = "0.1.0"
edition = "2024"
[workspace]
[dependencies]
-mingling_picker = { path = "../" }
+arg-picker = { path = "../" }
diff --git a/mingling_picker/test/src/lib.rs b/arg_picker/test/src/lib.rs
index eac6cad..0cfa575 100644
--- a/mingling_picker/test/src/lib.rs
+++ b/arg_picker/test/src/lib.rs
@@ -7,7 +7,7 @@
#[cfg(test)]
mod test;
-use mingling_picker::parselib::MaskedArg;
+use arg_picker::parselib::MaskedArg;
/// Create a single `MaskedArg` from a raw string and its original index.
pub fn make_masked(raw: &str, idx: usize) -> MaskedArg<'_> {
diff --git a/mingling_picker/test/src/test.rs b/arg_picker/test/src/test.rs
index 9c53514..9c53514 100644
--- a/mingling_picker/test/src/test.rs
+++ b/arg_picker/test/src/test.rs
diff --git a/mingling_picker/test/src/test/arg_matcher_test.rs b/arg_picker/test/src/test/arg_matcher_test.rs
index 7b37bc8..d1d363e 100644
--- a/mingling_picker/test/src/test/arg_matcher_test.rs
+++ b/arg_picker/test/src/test/arg_matcher_test.rs
@@ -1,5 +1,5 @@
-use mingling_picker::PickerArgInfo;
-use mingling_picker::parselib::{ArgMatcher, Matcher, POWERSHELL_STYLE, UNIX_STYLE};
+use arg_picker::parselib::{ArgMatcher, Matcher, POWERSHELL_STYLE, UNIX_STYLE};
+use arg_picker::PickerArgInfo;
use crate::make_args;
diff --git a/mingling_picker/test/src/test/basic_test.rs b/arg_picker/test/src/test/basic_test.rs
index 78b154e..b01adb6 100644
--- a/mingling_picker/test/src/test/basic_test.rs
+++ b/arg_picker/test/src/test/basic_test.rs
@@ -1,4 +1,4 @@
-use mingling_picker::{IntoPicker, macros::arg};
+use arg_picker::{macros::arg, IntoPicker};
// Basic bool flag — present / absent
diff --git a/mingling_picker/test/src/test/multi_arg_test.rs b/arg_picker/test/src/test/multi_arg_test.rs
index 377357e..49517f1 100644
--- a/mingling_picker/test/src/test/multi_arg_test.rs
+++ b/arg_picker/test/src/test/multi_arg_test.rs
@@ -1,5 +1,5 @@
-use mingling_picker::parselib::{Matcher, MultiArgMatcher, UNIX_STYLE};
-use mingling_picker::PickerArgInfo;
+use arg_picker::parselib::{Matcher, MultiArgMatcher, UNIX_STYLE};
+use arg_picker::PickerArgInfo;
use crate::make_args;
@@ -72,8 +72,12 @@ fn test_multi_all_two_occurrences() {
let mut info = PickerArgInfo::new();
info.set_long("val");
let args = make_args(&[
- ("--val", 0), ("a", 1), ("b", 2),
- ("--val", 3), ("c", 4), ("d", 5),
+ ("--val", 0),
+ ("a", 1),
+ ("b", 2),
+ ("--val", 3),
+ ("c", 4),
+ ("d", 5),
]);
let result = MultiArgMatcher::on_match_all(&args, &UNIX_STYLE, &info);
assert_eq!(result, vec![0, 1, 2, 3, 4, 5]);
@@ -85,9 +89,12 @@ fn test_multi_all_skips_non_matching_args() {
let mut info = PickerArgInfo::new();
info.set_long("val");
let args = make_args(&[
- ("--val", 0), ("a", 1),
- ("--other", 2), ("b", 3),
- ("--val", 4), ("c", 5),
+ ("--val", 0),
+ ("a", 1),
+ ("--other", 2),
+ ("b", 3),
+ ("--val", 4),
+ ("c", 5),
]);
let result = MultiArgMatcher::on_match_all(&args, &UNIX_STYLE, &info);
assert_eq!(result, vec![0, 1, 4, 5]);
@@ -120,9 +127,7 @@ fn test_multi_all_mixed_eq_and_regular() {
// --val=a b --val c d
let mut info = PickerArgInfo::new();
info.set_long("val");
- let args = make_args(&[
- ("--val=a", 0), ("b", 1), ("--val", 2), ("c", 3), ("d", 4),
- ]);
+ let args = make_args(&[("--val=a", 0), ("b", 1), ("--val", 2), ("c", 3), ("d", 4)]);
let result = MultiArgMatcher::on_match_all(&args, &UNIX_STYLE, &info);
assert_eq!(result, vec![0, 1, 2, 3, 4]);
}
diff --git a/mingling_picker/test/src/test/multi_value_test.rs b/arg_picker/test/src/test/multi_value_test.rs
index 0f56517..cbae645 100644
--- a/mingling_picker/test/src/test/multi_value_test.rs
+++ b/arg_picker/test/src/test/multi_value_test.rs
@@ -1,5 +1,5 @@
-use mingling_picker::value::{Flag, VecUntil};
-use mingling_picker::{IntoPicker, macros::arg};
+use arg_picker::value::{Flag, VecUntil};
+use arg_picker::{macros::arg, IntoPicker};
#[test]
fn test_vec_until_i16_named() {
diff --git a/mingling_picker/test/src/test/pos_matcher_test.rs b/arg_picker/test/src/test/pos_matcher_test.rs
index b5319f5..0d4f87e 100644
--- a/mingling_picker/test/src/test/pos_matcher_test.rs
+++ b/arg_picker/test/src/test/pos_matcher_test.rs
@@ -1,5 +1,5 @@
-use mingling_picker::PickerArgInfo;
-use mingling_picker::parselib::{MaskedArg, Matcher, PositionalMatcher, UNIX_STYLE, WINDOWS_STYLE};
+use arg_picker::parselib::{MaskedArg, Matcher, PositionalMatcher, UNIX_STYLE, WINDOWS_STYLE};
+use arg_picker::PickerArgInfo;
fn make_args<'a>(pairs: &'a [(&'a str, usize)]) -> Vec<MaskedArg<'a>> {
pairs
diff --git a/mingling_picker/test/src/test/priority_test.rs b/arg_picker/test/src/test/priority_test.rs
index 8179389..8f0a452 100644
--- a/mingling_picker/test/src/test/priority_test.rs
+++ b/arg_picker/test/src/test/priority_test.rs
@@ -1,5 +1,5 @@
-use mingling_picker::value::Flag;
-use mingling_picker::{IntoPicker, macros::arg};
+use arg_picker::value::Flag;
+use arg_picker::{macros::arg, IntoPicker};
// Same flag name, different Pickable types
//
diff --git a/mingling_picker/test/src/test/route_test.rs b/arg_picker/test/src/test/route_test.rs
index 9261db1..7594c6e 100644
--- a/mingling_picker/test/src/test/route_test.rs
+++ b/arg_picker/test/src/test/route_test.rs
@@ -1,4 +1,4 @@
-use mingling_picker::{IntoPicker, macros::arg};
+use arg_picker::{macros::arg, IntoPicker};
// Route mechanism — or_route
diff --git a/mingling_picker/test/src/test/style_test.rs b/arg_picker/test/src/test/style_test.rs
index 3c337b9..b470d4f 100644
--- a/mingling_picker/test/src/test/style_test.rs
+++ b/arg_picker/test/src/test/style_test.rs
@@ -1,8 +1,8 @@
-use mingling_picker::PickerArgInfo;
-use mingling_picker::parselib::{
- FlagMatcher, Matcher, POWERSHELL_STYLE, ParserStyle, ParserStyleNamingCase, UNIX_STYLE,
- WINDOWS_STYLE, build_possible_flags,
+use arg_picker::parselib::{
+ build_possible_flags, FlagMatcher, Matcher, ParserStyle, ParserStyleNamingCase,
+ POWERSHELL_STYLE, UNIX_STYLE, WINDOWS_STYLE,
};
+use arg_picker::PickerArgInfo;
use crate::make_masked;
diff --git a/mingling_picker/test/src/test/value_flag_test.rs b/arg_picker/test/src/test/value_flag_test.rs
index d267a27..3df053e 100644
--- a/mingling_picker/test/src/test/value_flag_test.rs
+++ b/arg_picker/test/src/test/value_flag_test.rs
@@ -1,5 +1,5 @@
-use mingling_picker::value::Flag;
-use mingling_picker::{IntoPicker, macros::arg};
+use arg_picker::value::Flag;
+use arg_picker::{macros::arg, IntoPicker};
// Basic Flag — present / absent
diff --git a/mingling_picker/test/src/test/value_string_test.rs b/arg_picker/test/src/test/value_string_test.rs
index b1e5c0b..2c3b50b 100644
--- a/mingling_picker/test/src/test/value_string_test.rs
+++ b/arg_picker/test/src/test/value_string_test.rs
@@ -1,4 +1,4 @@
-use mingling_picker::{IntoPicker, macros::arg};
+use arg_picker::{macros::arg, IntoPicker};
// Basic named String — present / absent
diff --git a/mingling_picker_macros/Cargo.toml b/arg_picker_macros/Cargo.toml
index 58488ea..c83cb9e 100644
--- a/mingling_picker_macros/Cargo.toml
+++ b/arg_picker_macros/Cargo.toml
@@ -1,9 +1,9 @@
[package]
-name = "mingling_picker_macros"
-version.workspace = true
-edition.workspace = true
-license.workspace = true
-repository.workspace = true
+name = "arg-picker-macros"
+version = "0.1.0"
+edition = "2024"
+license = "MIT OR Apache-2.0"
+repository = "https://github.com/mingling-rs/mingling/tree/main/arg-picker"
authors = ["Weicao-CatilGrass"]
readme = "README.md"
description = "Mingling's lightweight argument parser macros"
diff --git a/mingling_picker_macros/README.md b/arg_picker_macros/README.md
index 5a3f220..5a3f220 100644
--- a/mingling_picker_macros/README.md
+++ b/arg_picker_macros/README.md
diff --git a/mingling_picker_macros/src/arg.rs b/arg_picker_macros/src/arg.rs
index 70b27b0..55860c4 100644
--- a/mingling_picker_macros/src/arg.rs
+++ b/arg_picker_macros/src/arg.rs
@@ -73,7 +73,7 @@ pub(crate) fn arg(input: TokenStream) -> TokenStream {
let import = quote! { ::mingling::picker::PickerArg };
#[cfg(not(feature = "mingling_support"))]
- let import = quote! { ::mingling_picker::PickerArg };
+ let import = quote! { ::arg_picker::PickerArg };
if ty.is_some() {
quote! { #import::<#ty_ts> }
diff --git a/mingling_picker_macros/src/internal_repeat.rs b/arg_picker_macros/src/internal_repeat.rs
index 4b2242b..4b2242b 100644
--- a/mingling_picker_macros/src/internal_repeat.rs
+++ b/arg_picker_macros/src/internal_repeat.rs
diff --git a/mingling_picker_macros/src/lib.rs b/arg_picker_macros/src/lib.rs
index a12e3ed..18cce84 100644
--- a/mingling_picker_macros/src/lib.rs
+++ b/arg_picker_macros/src/lib.rs
@@ -18,7 +18,7 @@ pub fn internal_repeat(input: TokenStream) -> TokenStream {
/// # Syntax
///
/// ```ignore
-/// use mingling_picker_macros::flag;
+/// use arg_picker_macros::flag;
///
/// let basic = arg![name: String];
/// let with_short_name = arg![name: String, 'n'];
diff --git a/mingling/Cargo.toml b/mingling/Cargo.toml
index c3f9511..adf900f 100644
--- a/mingling/Cargo.toml
+++ b/mingling/Cargo.toml
@@ -50,7 +50,7 @@ dispatch_tree = ["mingling_core/dispatch_tree", "mingling_macros/dispatch_tree"]
repl = ["mingling_core/repl", "mingling_macros/repl"]
comp = ["mingling_core/comp", "mingling_macros/comp"]
parser = ["dep:size"]
-picker = ["dep:mingling_picker", "mingling_picker/mingling_support"]
+picker = ["dep:arg-picker", "arg-picker/mingling_support"]
pathf = ["mingling_core/pathf", "mingling_macros/pathf"]
structural_renderer = [
@@ -90,6 +90,6 @@ extra_macros = ["mingling_macros/extra_macros"]
[dependencies]
mingling_core = { workspace = true, optional = true }
mingling_macros = { workspace = true, optional = true }
-mingling_picker = { workspace = true, optional = true }
+arg-picker = { workspace = true, optional = true }
serde = { workspace = true, optional = true }
size = { version = "0.5", optional = true }
diff --git a/mingling/src/lib.rs b/mingling/src/lib.rs
index ba87f85..44812d6 100644
--- a/mingling/src/lib.rs
+++ b/mingling/src/lib.rs
@@ -86,10 +86,10 @@ pub mod parser;
/// `Mingling` argument parser (Picker2)
#[cfg(feature = "picker")]
pub mod picker {
- pub use mingling_picker::*;
+ pub use arg_picker::*;
pub mod parselib {
- pub use mingling_picker::parselib::*;
+ pub use arg_picker::parselib::*;
}
}
@@ -107,6 +107,9 @@ pub mod picker {
#[allow(unused_imports)]
#[cfg(feature = "macros")]
pub mod macros {
+ /// New Parser provided by the `picker` feature
+ #[cfg(feature = "picker")]
+ pub use arg_picker::macros::*;
/// `#[chain]` - Used to generate a struct implementing the `Chain` trait via a method
pub use mingling_macros::chain;
/// `#[completion(EntryType)]` - Used to generate completion entry
@@ -177,9 +180,6 @@ pub mod macros {
/// `suggest_enum!(EnumNames)` - Used to generate enum suggestions
#[cfg(feature = "comp")]
pub use mingling_macros::suggest_enum;
- /// New Parser provided by the `picker` feature
- #[cfg(feature = "picker")]
- pub use mingling_picker::macros::*;
}
/// derive macro `EnumTag`
@@ -286,7 +286,7 @@ pub mod prelude {
pub use crate::parser::AsPicker;
#[cfg(feature = "picker")]
- pub use mingling_picker::prelude::*;
+ pub use arg_picker::prelude::*;
/// Used to enable the `writeln!` macro for `RenderResult`
#[cfg(feature = "core")]
diff --git a/mingling_picker/Cargo.toml b/mingling_picker/Cargo.toml
deleted file mode 100644
index ddab33c..0000000
--- a/mingling_picker/Cargo.toml
+++ /dev/null
@@ -1,17 +0,0 @@
-[package]
-name = "mingling_picker"
-version.workspace = true
-edition.workspace = true
-license.workspace = true
-repository.workspace = true
-authors = ["Weicao-CatilGrass"]
-readme = "README.md"
-description = "Mingling's lightweight argument parser"
-
-[features]
-mingling_support = ["dep:mingling_core", "mingling_picker_macros/mingling_support"]
-
-[dependencies]
-mingling_core = { workspace = true, optional = true }
-mingling_picker_macros.workspace = true
-just_fmt.workspace = true