aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.cargo/config.toml4
-rw-r--r--.github/workflows/ci.yml6
-rw-r--r--.run/.gitignore7
-rw-r--r--.run/Cargo.lock (renamed from dev_tools/Cargo.lock)0
-rw-r--r--.run/Cargo.toml (renamed from dev_tools/Cargo.toml)2
-rw-r--r--.run/src/bin/build-all.ps1 (renamed from dev_tools/scripts/build-all.ps1)0
-rw-r--r--[-rwxr-xr-x].run/src/bin/build-all.sh (renamed from dev_tools/scripts/build-all.sh)0
-rw-r--r--.run/src/bin/ci.rs (renamed from dev_tools/src/bin/ci.rs)14
-rw-r--r--.run/src/bin/clippy-fix.ps1 (renamed from dev_tools/scripts/clippy-fix.ps1)0
-rw-r--r--[-rwxr-xr-x].run/src/bin/clippy-fix.sh (renamed from dev_tools/scripts/clippy-fix.sh)0
-rw-r--r--.run/src/bin/clippy.ps1 (renamed from dev_tools/scripts/clippy.ps1)0
-rw-r--r--[-rwxr-xr-x].run/src/bin/clippy.sh (renamed from dev_tools/scripts/clippy.sh)0
-rw-r--r--[-rwxr-xr-x].run/src/bin/doc.ps1 (renamed from dev_tools/scripts/doc.ps1)0
-rw-r--r--[-rwxr-xr-x].run/src/bin/doc.sh (renamed from dev_tools/scripts/doc.sh)0
-rw-r--r--.run/src/bin/docs-code-box-fix.rs (renamed from dev_tools/src/bin/docs-code-box-fix.rs)0
-rw-r--r--.run/src/bin/docsify-sidebar-gen.rs (renamed from dev_tools/src/bin/docsify-sidebar-gen.rs)15
-rw-r--r--.run/src/bin/http-page-preview.ps1 (renamed from dev_tools/scripts/http-page-preview.ps1)0
-rw-r--r--[-rwxr-xr-x].run/src/bin/http-page-preview.sh (renamed from dev_tools/scripts/http-page-preview.sh)0
-rw-r--r--[-rwxr-xr-x].run/src/bin/install-mling.ps1 (renamed from dev_tools/scripts/install-mling.ps1)0
-rw-r--r--[-rwxr-xr-x].run/src/bin/install-mling.sh (renamed from dev_tools/scripts/install-mling.sh)0
-rw-r--r--.run/src/bin/refresh-docs.rs (renamed from dev_tools/src/bin/refresh-docs.rs)0
-rw-r--r--.run/src/bin/refresh-feature-mod.rs (renamed from dev_tools/src/bin/refresh-feature-mod.rs)0
-rw-r--r--.run/src/bin/sync-examples.rs (renamed from dev_tools/src/bin/sync-examples.rs)0
-rw-r--r--.run/src/bin/test-all-markdown-code.rs (renamed from dev_tools/src/bin/test-all-markdown-code.rs)0
-rw-r--r--.run/src/bin/test-all.ps1 (renamed from dev_tools/scripts/test-all.ps1)0
-rw-r--r--.run/src/bin/test-all.sh (renamed from dev_tools/scripts/test-all.sh)0
-rw-r--r--.run/src/bin/test-examples.rs (renamed from dev_tools/src/bin/test-examples.rs)0
-rw-r--r--.run/src/bin/update-version.rs (renamed from dev_tools/src/bin/update-version.rs)18
-rw-r--r--.run/src/bin/windows-folder-hide.ps1 (renamed from dev_tools/scripts/windows-folder-hide.ps1)0
-rw-r--r--.run/src/lib.rs (renamed from dev_tools/src/lib.rs)4
-rw-r--r--.run/src/verify.rs (renamed from dev_tools/src/verify.rs)4
-rw-r--r--.run/version-files.toml (renamed from dev_tools/version-files.toml)0
-rw-r--r--ABOUT-CI.md22
-rw-r--r--CHANGELOG.md279
-rw-r--r--CONTRIBUTING.md54
-rw-r--r--Cargo.lock30
-rw-r--r--Cargo.toml10
-rw-r--r--README.md4
-rw-r--r--docs/_zh_CN/pages/1-getting-started.md4
-rw-r--r--docs/dev-docs/README.md15
-rw-r--r--docs/dev-docs/pages/abouts/.name1
-rw-r--r--docs/dev-docs/pages/issues/.name1
-rw-r--r--docs/dev/README.md21
-rw-r--r--docs/dev/_sidebar.md (renamed from docs/dev-docs/_sidebar.md)11
-rw-r--r--docs/dev/index.html (renamed from docs/dev-docs/index.html)0
-rw-r--r--docs/dev/pages/abouts/.name1
-rw-r--r--docs/dev/pages/abouts/ai-translation-rule.md (renamed from docs/dev-docs/pages/abouts/ai-translation-rule.md)0
-rw-r--r--docs/dev/pages/abouts/code-verify-system.md (renamed from docs/dev-docs/pages/abouts/code-verify-system.md)0
-rw-r--r--docs/dev/pages/issues/.name1
-rw-r--r--docs/dev/pages/issues/remove-r-print-macro.md97
-rw-r--r--docs/dev/pages/issues/the-mod-pathfinder.md (renamed from docs/dev-docs/pages/issues/the-mod-pathfinder.md)0
-rw-r--r--docs/dev/pages/issues/the-shit-time.md (renamed from docs/dev-docs/pages/issues/the-shit-time.md)10
-rw-r--r--docs/dev/pages/templates/.name1
-rw-r--r--docs/dev/pages/templates/doc.md (renamed from docs/dev-docs/pages/templates/doc.md)0
-rw-r--r--docs/pages/1-getting-started.md4
-rw-r--r--docs/res/guide.txt2
-rw-r--r--examples/example-argument-parse/Cargo.lock10
-rw-r--r--examples/example-async-support/Cargo.lock10
-rw-r--r--examples/example-basic/Cargo.lock10
-rw-r--r--examples/example-clap-binding/Cargo.lock10
-rw-r--r--examples/example-combine-pathf-dispatch-tree/Cargo.lock14
-rw-r--r--examples/example-completion/Cargo.lock10
-rw-r--r--examples/example-custom-pickable/Cargo.lock10
-rw-r--r--examples/example-dispatch-tree/Cargo.lock10
-rw-r--r--examples/example-enum-tag/Cargo.lock10
-rw-r--r--examples/example-error-handling/Cargo.lock10
-rw-r--r--examples/example-exitcode/Cargo.lock10
-rw-r--r--examples/example-help/Cargo.lock10
-rw-r--r--examples/example-hook/Cargo.lock10
-rw-r--r--examples/example-implicit-dispatcher/Cargo.lock10
-rw-r--r--examples/example-lazy-resources/Cargo.lock10
-rw-r--r--examples/example-outside-type/Cargo.lock10
-rw-r--r--examples/example-pack-err/Cargo.lock10
-rw-r--r--examples/example-panic-unwind/Cargo.lock10
-rw-r--r--examples/example-pathfinder/Cargo.lock14
-rw-r--r--examples/example-repl-basic/Cargo.lock10
-rw-r--r--examples/example-resources/Cargo.lock10
-rw-r--r--examples/example-setup/Cargo.lock10
-rw-r--r--examples/example-structural-renderer/Cargo.lock10
-rw-r--r--examples/example-unit-test/Cargo.lock10
-rw-r--r--examples/full-todolist/Cargo.lock10
-rw-r--r--mingling_core/tests/test-all/Cargo.lock10
-rw-r--r--mingling_core/tests/test-basic/Cargo.lock10
-rw-r--r--mingling_core/tests/test-comp/Cargo.lock10
-rw-r--r--mingling_core/tests/test-dispatch-tree/Cargo.lock10
-rw-r--r--mingling_core/tests/test-repl/Cargo.lock10
-rw-r--r--mingling_core/tests/test-structural-renderer/Cargo.lock10
-rw-r--r--mingling_macros/src/structural_data.rs11
-rw-r--r--mingling_pathf/test/Cargo.lock2
-rw-r--r--mling/res/template_0.2/command/Cargo.toml.tmpl (renamed from docs/dev-docs/pages/templates/.name)0
-rw-r--r--mling/res/template_0.2/flat/Cargo.toml.tmpl (renamed from mling/res/template_0.2/command/Cargo.toml)0
-rw-r--r--mling/res/template_0.2/modularity/Cargo.toml0
-rw-r--r--mling/res/template_0.2/modularity/Cargo.toml.tmpl (renamed from mling/res/template_0.2/flat/Cargo.toml)0
-rw-r--r--run-tools.ps160
-rwxr-xr-xrun-tools.sh64
-rw-r--r--run.ps1232
-rw-r--r--run.sh257
97 files changed, 1056 insertions, 530 deletions
diff --git a/.cargo/config.toml b/.cargo/config.toml
index 0b45ca9..f375b03 100644
--- a/.cargo/config.toml
+++ b/.cargo/config.toml
@@ -4,5 +4,5 @@ target-dir = "./.temp/target"
[env]
[alias]
-ci = "run --manifest-path dev_tools/Cargo.toml --bin ci --quiet --"
-dev_tool = "run --manifest-path dev_tools/Cargo.toml --quiet --bin "
+ci = "run --manifest-path .run/Cargo.toml --bin ci --quiet --"
+dev_tool = "run --manifest-path .run/Cargo.toml --quiet --bin "
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 9ff16cb..faa513a 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -62,6 +62,10 @@ jobs:
Deploy-Github-Pages:
needs: [Move-Unreleased-Tag]
+ permissions:
+ contents: read
+ pages: write
+ id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
@@ -77,4 +81,4 @@ jobs:
path: "."
- name: Deploy to GitHub Pages
id: deployment
- uses: actions/deploy-pages@v4
+ uses: actions/deploy-pages@v5
diff --git a/.run/.gitignore b/.run/.gitignore
new file mode 100644
index 0000000..0dc39b0
--- /dev/null
+++ b/.run/.gitignore
@@ -0,0 +1,7 @@
+# All temp build artifacts will be stored in this dir
+/target
+
+# If you want to add some Rust crates? Remove this line
+# /Cargo.*
+
+last_check
diff --git a/dev_tools/Cargo.lock b/.run/Cargo.lock
index bb510bd..bb510bd 100644
--- a/dev_tools/Cargo.lock
+++ b/.run/Cargo.lock
diff --git a/dev_tools/Cargo.toml b/.run/Cargo.toml
index 9855580..283aa47 100644
--- a/dev_tools/Cargo.toml
+++ b/.run/Cargo.toml
@@ -19,3 +19,5 @@ serde = { version = "1", features = ["derive"] }
serde_json = "1"
tokio = { version = "1", features = ["rt-multi-thread", "macros"] }
indicatif = "0.18.4"
+
+[workspace]
diff --git a/dev_tools/scripts/build-all.ps1 b/.run/src/bin/build-all.ps1
index 4f35ed8..4f35ed8 100644
--- a/dev_tools/scripts/build-all.ps1
+++ b/.run/src/bin/build-all.ps1
diff --git a/dev_tools/scripts/build-all.sh b/.run/src/bin/build-all.sh
index 2036b41..2036b41 100755..100644
--- a/dev_tools/scripts/build-all.sh
+++ b/.run/src/bin/build-all.sh
diff --git a/dev_tools/src/bin/ci.rs b/.run/src/bin/ci.rs
index f8aed79..2527ece 100644
--- a/dev_tools/src/bin/ci.rs
+++ b/.run/src/bin/ci.rs
@@ -139,12 +139,12 @@ fn ci(test_docs: bool, test_codes: bool, run_all: bool) -> Result<(), i32> {
}
fn test_examples() -> Result<(), i32> {
- run_cmd!("cargo run --manifest-path dev_tools/Cargo.toml --color always --bin test-examples")
+ run_cmd!("cargo run --manifest-path .run/Cargo.toml --color always --bin test-examples")
}
fn test_docs_code_blocks() -> Result<(), i32> {
run_cmd!(
- "cargo run --manifest-path dev_tools/Cargo.toml --color always --bin test-all-markdown-code"
+ "cargo run --manifest-path .run/Cargo.toml --color always --bin test-all-markdown-code"
)
}
@@ -214,11 +214,11 @@ fn test_all() -> Result<(), i32> {
fn docs_refresh() -> Result<(), i32> {
println_cargo_style!("Refresh: document at `./docs/`");
- run_cmd!("cargo run --manifest-path dev_tools/Cargo.toml --bin docs-code-box-fix")?;
- run_cmd!("cargo run --manifest-path dev_tools/Cargo.toml --bin docsify-sidebar-gen")?;
- run_cmd!("cargo run --manifest-path dev_tools/Cargo.toml --bin refresh-docs")?;
- run_cmd!("cargo run --manifest-path dev_tools/Cargo.toml --bin refresh-feature-mod")?;
- run_cmd!("cargo run --manifest-path dev_tools/Cargo.toml --bin sync-examples")?;
+ run_cmd!("cargo run --manifest-path .run/Cargo.toml --bin docs-code-box-fix")?;
+ run_cmd!("cargo run --manifest-path .run/Cargo.toml --bin docsify-sidebar-gen")?;
+ run_cmd!("cargo run --manifest-path .run/Cargo.toml --bin refresh-docs")?;
+ run_cmd!("cargo run --manifest-path .run/Cargo.toml --bin refresh-feature-mod")?;
+ run_cmd!("cargo run --manifest-path .run/Cargo.toml --bin sync-examples")?;
run_cmd!("cargo fmt")?;
Ok(())
diff --git a/dev_tools/scripts/clippy-fix.ps1 b/.run/src/bin/clippy-fix.ps1
index 1d24f92..1d24f92 100644
--- a/dev_tools/scripts/clippy-fix.ps1
+++ b/.run/src/bin/clippy-fix.ps1
diff --git a/dev_tools/scripts/clippy-fix.sh b/.run/src/bin/clippy-fix.sh
index 9771ad4..9771ad4 100755..100644
--- a/dev_tools/scripts/clippy-fix.sh
+++ b/.run/src/bin/clippy-fix.sh
diff --git a/dev_tools/scripts/clippy.ps1 b/.run/src/bin/clippy.ps1
index 1858873..1858873 100644
--- a/dev_tools/scripts/clippy.ps1
+++ b/.run/src/bin/clippy.ps1
diff --git a/dev_tools/scripts/clippy.sh b/.run/src/bin/clippy.sh
index b393545..b393545 100755..100644
--- a/dev_tools/scripts/clippy.sh
+++ b/.run/src/bin/clippy.sh
diff --git a/dev_tools/scripts/doc.ps1 b/.run/src/bin/doc.ps1
index 987f0de..987f0de 100755..100644
--- a/dev_tools/scripts/doc.ps1
+++ b/.run/src/bin/doc.ps1
diff --git a/dev_tools/scripts/doc.sh b/.run/src/bin/doc.sh
index 5e8a311..5e8a311 100755..100644
--- a/dev_tools/scripts/doc.sh
+++ b/.run/src/bin/doc.sh
diff --git a/dev_tools/src/bin/docs-code-box-fix.rs b/.run/src/bin/docs-code-box-fix.rs
index 21d2cce..21d2cce 100644
--- a/dev_tools/src/bin/docs-code-box-fix.rs
+++ b/.run/src/bin/docs-code-box-fix.rs
diff --git a/dev_tools/src/bin/docsify-sidebar-gen.rs b/.run/src/bin/docsify-sidebar-gen.rs
index b926112..5beda7f 100644
--- a/dev_tools/src/bin/docsify-sidebar-gen.rs
+++ b/.run/src/bin/docsify-sidebar-gen.rs
@@ -43,7 +43,7 @@ fn find_all_readmes(dir: &Path) -> Vec<PathBuf> {
let path = entry.path();
if path.is_dir() {
results.extend(find_all_readmes(&path));
- } else if path.file_name().map_or(false, |n| n == "README.md") {
+ } else if path.file_name().is_some_and(|n| n == "README.md") {
results.push(path);
}
}
@@ -67,11 +67,10 @@ fn find_content_dir(site_root: &Path) -> Option<PathBuf> {
entries.sort_by_key(|e| e.path());
for entry in entries {
let path = entry.path();
- if path.is_dir() {
- if has_markdown_files(&path) {
+ if path.is_dir()
+ && has_markdown_files(&path) {
return Some(path);
}
- }
}
}
@@ -254,12 +253,10 @@ fn natural_cmp(a: &str, b: &str) -> std::cmp::Ordering {
/// Looks at the filename stem (after the last `/`) for a number before the first `-`.
/// Returns `usize::MAX` for entries without a numeric prefix.
fn extract_leading_number(link: &str) -> usize {
- if let Some(file_stem) = link.rsplit('/').next() {
- if let Some(num_end) = file_stem.find('-') {
- if let Ok(num) = file_stem[..num_end].parse::<usize>() {
+ if let Some(file_stem) = link.rsplit('/').next()
+ && let Some(num_end) = file_stem.find('-')
+ && let Ok(num) = file_stem[..num_end].parse::<usize>() {
return num;
}
- }
- }
usize::MAX
}
diff --git a/dev_tools/scripts/http-page-preview.ps1 b/.run/src/bin/http-page-preview.ps1
index 8cc3579..8cc3579 100644
--- a/dev_tools/scripts/http-page-preview.ps1
+++ b/.run/src/bin/http-page-preview.ps1
diff --git a/dev_tools/scripts/http-page-preview.sh b/.run/src/bin/http-page-preview.sh
index bed4b1c..bed4b1c 100755..100644
--- a/dev_tools/scripts/http-page-preview.sh
+++ b/.run/src/bin/http-page-preview.sh
diff --git a/dev_tools/scripts/install-mling.ps1 b/.run/src/bin/install-mling.ps1
index bebe9ff..bebe9ff 100755..100644
--- a/dev_tools/scripts/install-mling.ps1
+++ b/.run/src/bin/install-mling.ps1
diff --git a/dev_tools/scripts/install-mling.sh b/.run/src/bin/install-mling.sh
index 5f2ee7a..5f2ee7a 100755..100644
--- a/dev_tools/scripts/install-mling.sh
+++ b/.run/src/bin/install-mling.sh
diff --git a/dev_tools/src/bin/refresh-docs.rs b/.run/src/bin/refresh-docs.rs
index 82ef906..82ef906 100644
--- a/dev_tools/src/bin/refresh-docs.rs
+++ b/.run/src/bin/refresh-docs.rs
diff --git a/dev_tools/src/bin/refresh-feature-mod.rs b/.run/src/bin/refresh-feature-mod.rs
index 2255dbc..2255dbc 100644
--- a/dev_tools/src/bin/refresh-feature-mod.rs
+++ b/.run/src/bin/refresh-feature-mod.rs
diff --git a/dev_tools/src/bin/sync-examples.rs b/.run/src/bin/sync-examples.rs
index 0923b33..0923b33 100644
--- a/dev_tools/src/bin/sync-examples.rs
+++ b/.run/src/bin/sync-examples.rs
diff --git a/dev_tools/src/bin/test-all-markdown-code.rs b/.run/src/bin/test-all-markdown-code.rs
index 280fca7..280fca7 100644
--- a/dev_tools/src/bin/test-all-markdown-code.rs
+++ b/.run/src/bin/test-all-markdown-code.rs
diff --git a/dev_tools/scripts/test-all.ps1 b/.run/src/bin/test-all.ps1
index 231698a..231698a 100644
--- a/dev_tools/scripts/test-all.ps1
+++ b/.run/src/bin/test-all.ps1
diff --git a/dev_tools/scripts/test-all.sh b/.run/src/bin/test-all.sh
index b387463..b387463 100644
--- a/dev_tools/scripts/test-all.sh
+++ b/.run/src/bin/test-all.sh
diff --git a/dev_tools/src/bin/test-examples.rs b/.run/src/bin/test-examples.rs
index 539459e..539459e 100644
--- a/dev_tools/src/bin/test-examples.rs
+++ b/.run/src/bin/test-examples.rs
diff --git a/dev_tools/src/bin/update-version.rs b/.run/src/bin/update-version.rs
index 475e54b..9d595bb 100644
--- a/dev_tools/src/bin/update-version.rs
+++ b/.run/src/bin/update-version.rs
@@ -39,7 +39,9 @@ fn main() {
let root_cargo_path = "Cargo.toml";
let root_cargo_content =
std::fs::read_to_string(root_cargo_path).expect("Failed to read Cargo.toml");
- let cargo_value: toml::Value = root_cargo_content.parse().expect("Failed to parse Cargo.toml");
+ let cargo_value: toml::Value = root_cargo_content
+ .parse()
+ .expect("Failed to parse Cargo.toml");
let current_ver = cargo_value["workspace"]["package"]["version"]
.as_str()
@@ -54,11 +56,11 @@ fn main() {
println_cargo_style!("Version: {} -> {}", current_ver, new_ver);
// Read version-files.toml
- let config_path = Path::new("dev_tools").join("version-files.toml");
+ let config_path = Path::new(".run").join("version-files.toml");
let config_str =
- std::fs::read_to_string(&config_path).expect("Failed to read dev_tools/version-files.toml");
- let config: Config = toml::from_str(&config_str)
- .expect("Failed to parse dev_tools/version-files.toml");
+ std::fs::read_to_string(&config_path).expect("Failed to read .run/version-files.toml");
+ let config: Config =
+ toml::from_str(&config_str).expect("Failed to parse .run/version-files.toml");
let mut updated_count = 0;
let mut skipped_count = 0;
@@ -94,5 +96,9 @@ fn main() {
updated_count += 1;
}
- println_cargo_style!("Done: {} file(s) updated, {} file(s) skipped", updated_count, skipped_count);
+ println_cargo_style!(
+ "Done: {} file(s) updated, {} file(s) skipped",
+ updated_count,
+ skipped_count
+ );
}
diff --git a/dev_tools/scripts/windows-folder-hide.ps1 b/.run/src/bin/windows-folder-hide.ps1
index 0ab2632..0ab2632 100644
--- a/dev_tools/scripts/windows-folder-hide.ps1
+++ b/.run/src/bin/windows-folder-hide.ps1
diff --git a/dev_tools/src/lib.rs b/.run/src/lib.rs
index d38a156..232afb3 100644
--- a/dev_tools/src/lib.rs
+++ b/.run/src/lib.rs
@@ -316,8 +316,8 @@ pub fn cargo_tomls() -> Vec<std::path::PathBuf> {
for entry in entries.flatten() {
let path = entry.path();
if path.is_dir() {
- // Skip the dev_tools directory
- if path.file_name().and_then(|n| n.to_str()) == Some("dev_tools") {
+ // Skip the .run directory
+ if path.file_name().and_then(|n| n.to_str()) == Some(".run") {
continue;
}
dirs.push(path);
diff --git a/dev_tools/src/verify.rs b/.run/src/verify.rs
index 2ddff0c..0a4b354 100644
--- a/dev_tools/src/verify.rs
+++ b/.run/src/verify.rs
@@ -76,10 +76,10 @@ fn parse_single_block(lines: &[&str], start: usize, source_file: &str) -> Option
// @@@ lines: strip the prefix and treat as regular Rust code
// These lines are hidden in the rendered docs (filtered by a docsify plugin)
// but must still compile.
- if trimmed.starts_with("@@@") {
+ if let Some(stripped) = trimmed.strip_prefix("@@@") {
in_header = false;
// Strip @@@ and optionally one following space
- let code = trimmed[3..].trim_start();
+ let code = stripped.trim_start();
if code.contains("fn main") {
has_main = true;
}
diff --git a/dev_tools/version-files.toml b/.run/version-files.toml
index ca104d2..ca104d2 100644
--- a/dev_tools/version-files.toml
+++ b/.run/version-files.toml
diff --git a/ABOUT-CI.md b/ABOUT-CI.md
index 762fab8..4cbcd6f 100644
--- a/ABOUT-CI.md
+++ b/ABOUT-CI.md
@@ -1,6 +1,6 @@
# About Mingling CI Process
-Mingling's CI process is built into the project, with its execution logic located in `dev_tools/src/bin/ci.rs`. You can run it locally via the `cargo ci` command, which produces the same results as the `CI` workflow in GitHub Actions.
+Mingling's CI process is built into the project, with its execution logic located in `.run/src/bin/ci.rs`. You can run it locally via the `cargo ci` command, which produces the same results as the `CI` workflow in GitHub Actions.
During development, you can run `cargo ci` at any time to verify that your code hasn't introduced regressions.
@@ -10,7 +10,7 @@ An alias is defined in `.cargo/config.toml` at the project root:
```toml
[alias]
-ci = "run --manifest-path dev_tools/Cargo.toml --bin ci --quiet --"
+ci = "run --manifest-path .run/Cargo.toml --bin ci --quiet --"
```
Simply execute:
@@ -34,11 +34,11 @@ cargo ci
- **Test all examples**: Runs the `test-examples` tool.
- **Verify Markdown code blocks compile**: Runs the `test-all-markdown-code` tool to check code blocks in all `*.md` files. See [ABOUT_CODE_VERIFY](docs/_ABOUT_CODE_VERIFY.md) for details.
- **Check if documentation is up to date**: Runs the following documentation refresh tools in sequence:
- - `docs-code-box-fix`
- - `docsify-sidebar-gen`
- - `refresh-docs`
- - `refresh-feature-mod`
- - `sync-examples`
+ - `docs-code-box-fix`
+ - `docsify-sidebar-gen`
+ - `refresh-docs`
+ - `refresh-feature-mod`
+ - `sync-examples`
- Finally, runs `cargo fmt` to unify code formatting.
### 3. File Normalization
@@ -50,11 +50,11 @@ Runs `git add --renormalize .` to ensure file attributes such as line endings co
To ensure reproducible CI results, `ci.rs` imposes strict requirements on the workspace state:
- If the current workspace is not clean and `--dirty` has not been specified, the script will prompt whether to create a temporary commit:
- - The commit message is `[DO NOT PUSH] CI TEMP [DO NOT PUSH]`.
- - Use `-y` to auto-confirm without interaction.
+ - The commit message is `[DO NOT PUSH] CI TEMP [DO NOT PUSH]`.
+ - Use `-y` to auto-confirm without interaction.
- After CI finishes, the script automatically restores the workspace:
- - First, `git reset --hard` discards all changes.
- - If a temporary commit was created, it then runs `git reset --soft HEAD~1` and unstages everything, restoring the state to before CI started.
+ - First, `git reset --hard` discards all changes.
+ - If a temporary commit was created, it then runs `git reset --soft HEAD~1` and unstages everything, restoring the state to before CI started.
- If `--dirty` is specified, the temporary commit and the final cleanliness check are skipped.
> **Warning**: `git reset --hard` is executed at the end of CI. If you use `--dirty`, ensure you have no unsaved important changes.
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 05030d8..08538b3 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.2.2 (2026-07-10)](#release-022-2026-07-10)
- [Release 0.2.1 (2026-07-01)](#release-021-2026-07-01)
- [Release 0.2.0 (2026-06-30)](#release-020-2026-06-30)
- [Release 0.1.9 (2026-05-29)](#release-019-2026-05-29)
@@ -48,6 +49,28 @@ None
---
+## Release 0.2.2 (2026-07-10)
+
+### Unreleased
+
+#### Fixes:
+
+1. **[`macros:structural_data`]** Fixed `group_structural!` macro to correctly generate `use` statements for multi-segment type paths (e.g., `crate::MyType`). Previously, when an aliased type had only one segment, the macro used the alias name (`type_name`) instead of the original type's last segment for `super::` imports, which could cause compilation errors. Now correctly extracts the last segment from the original `type_path` for single-segment fallback imports.
+
+#### Optimizations:
+
+None
+
+#### Features:
+
+None
+
+#### **BREAKING CHANGES** (API CHANGES):
+
+None
+
+---
+
### Release 0.2.1 (2026-07-01)
#### Fixes:
@@ -57,7 +80,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:
@@ -86,36 +109,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.
@@ -126,33 +149,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:
@@ -354,20 +377,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.
@@ -401,29 +424,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
@@ -435,25 +458,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.
@@ -467,43 +490,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.
@@ -531,8 +554,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:
@@ -572,8 +595,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.
@@ -720,10 +743,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:
@@ -843,9 +866,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
@@ -1022,9 +1045,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 d90db4a..e8e4bed 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -6,46 +6,46 @@ 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 |
-| **Examples** | `examples/` | To add expected output tests, modify `examples/test-examples.toml` |
-| **Documentation, resources** | `docs/` | All documentation and resource files |
-| **Development tools** | `dev_tools/` | Contains scripts and Rust tools |
-| Scripts | `dev_tools/scripts/` | Helper `.sh`/`.ps1`/`.py` scripts, executed via `./run-tools.sh` or `.\run-tools.ps1` |
-| Rust tools | `dev_tools/src/bin/` | Same as above |
-| CI check entry | `dev_tools/src/bin/ci.rs` | Can be invoked directly via `cargo ci` |
-| **Scaffolding tool** | `mling/` | Scaffolding tool `mingling-cli` |
-| **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 |
+| **Examples** | `examples/` | To add expected output tests, modify `examples/test-examples.toml` |
+| **Documentation, resources** | `docs/` | All documentation and resource files |
+| **Development tools** | `.run/src/bin` | Contains scripts and Rust tools |
+| Scripts | `.run/src/bin` | Helper `.sh`/`.ps1`/`.py` scripts, executed via `./run.sh` or `.\run.ps1` |
+| Rust tools | `dev_tools/src/bin/` | Same as above |
+| CI check entry | `dev_tools/src/bin/ci.rs` | Can be invoked directly via `cargo ci` |
+| **Scaffolding tool** | `mling/` | Scaffolding tool `mingling-cli` |
+| **Temporary files** | `.temp/` | Ignored by `.gitignore` |
## 2. 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
## 3. Documentation Contribution
@@ -60,11 +60,11 @@ After editing documentation, refresh relevant files:
```bash
# Refresh sidebar and README sync
-./run-tools.sh docsify-sidebar-gen
-./run-tools.sh refresh-docs
+./run.sh docsify-sidebar-gen
+./run.sh refresh-docs
# Fix code block blank line issues
-./run-tools.sh docs-code-box-fix
+./run.sh docs-code-box-fix
```
These steps are included in `cargo ci`; running `cargo ci` will execute them automatically.
diff --git a/Cargo.lock b/Cargo.lock
index 57f3b8e..355bbc1 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -401,11 +401,11 @@ checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
[[package]]
name = "mingling"
-version = "0.2.1"
+version = "0.2.2"
dependencies = [
"mingling",
- "mingling_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "mingling_macros 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mingling_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mingling_macros 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde",
"size",
"tokio",
@@ -413,7 +413,7 @@ dependencies = [
[[package]]
name = "mingling-cli"
-version = "0.2.1"
+version = "0.2.2"
dependencies = [
"chrono",
"colored",
@@ -427,13 +427,13 @@ dependencies = [
[[package]]
name = "mingling_core"
-version = "0.2.1"
+version = "0.2.2"
dependencies = [
"env_logger",
"just_fmt",
"just_template",
"log",
- "mingling_pathf 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mingling_pathf 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"ron",
"serde",
"serde_json",
@@ -443,15 +443,15 @@ dependencies = [
[[package]]
name = "mingling_core"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c6a8751b43d4fd3d61d7b37f0d7f4d5d274d9391cf80cae9bd75f218219eefe"
+checksum = "b64318a9b61120f0deaf33c4ab9efc9313387dece2defd7841665242807634ea"
dependencies = [
"env_logger",
"just_fmt",
"just_template",
"log",
- "mingling_pathf 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mingling_pathf 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"ron",
"serde",
"serde_json",
@@ -461,7 +461,7 @@ dependencies = [
[[package]]
name = "mingling_macros"
-version = "0.2.1"
+version = "0.2.2"
dependencies = [
"just_fmt",
"proc-macro2",
@@ -471,9 +471,9 @@ dependencies = [
[[package]]
name = "mingling_macros"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7cd478387797590d2afb4122078649c3e4f9da7f29dbf37817763fecf04958f"
+checksum = "f29efa15f48e39fd4a06868030545b1938e5ba050929cd9a235525814bfb6367"
dependencies = [
"just_fmt",
"proc-macro2",
@@ -483,7 +483,7 @@ dependencies = [
[[package]]
name = "mingling_pathf"
-version = "0.2.1"
+version = "0.2.2"
dependencies = [
"just_fmt",
"proc-macro2",
@@ -492,9 +492,9 @@ dependencies = [
[[package]]
name = "mingling_pathf"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9d400d170c80e3f2f7d6f9b6739c286bc64279c805b770fabac390e3a7c7baf0"
+checksum = "134fb0a329f4cc605298eb47683cd2e9eaa184bf651215cbc72d411e9533a4be"
dependencies = [
"just_fmt",
"proc-macro2",
diff --git a/Cargo.toml b/Cargo.toml
index 499da03..201f88e 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -9,7 +9,7 @@ exclude = [
"examples/*",
# Dev Tools
- "dev_tools",
+ ".run",
# Tests
"mingling_core/tests/*",
@@ -17,9 +17,9 @@ exclude = [
]
[workspace.dependencies]
-mingling_core = { version = "0.2.1", default-features = false }
-mingling_macros = { version = "0.2.1", default-features = false }
-mingling_pathf = { version = "0.2.1", default-features = false }
+mingling_core = { version = "0.2.2", default-features = false }
+mingling_macros = { version = "0.2.2", default-features = false }
+mingling_pathf = { version = "0.2.2", default-features = false }
just_fmt = "0.1.2"
just_template = "0.2.0"
@@ -43,7 +43,7 @@ log = "0.4.33"
env_logger = "0.11.11"
[workspace.package]
-version = "0.2.1"
+version = "0.2.2"
edition = "2024"
license = "MIT OR Apache-2.0"
repository = "https://github.com/mingling-rs/mingling"
diff --git a/README.md b/README.md
index 9973aa5..e5d0a3c 100644
--- a/README.md
+++ b/README.md
@@ -54,7 +54,7 @@
- 📖 [Examples](https://mingling-rs.github.io/mingling/docs/examples.html)
- 📖 [docs.rs](https://docs.rs/mingling/latest/mingling/)
- 📖 [Helpdoc](https://mingling-rs.github.io/mingling/docs/doc.html#/) Or [帮助文档](https://mingling-rs.github.io/mingling/docs/_zh_CN/index.html#/)
-- 🔍 [Devdoc](https://mingling-rs.github.io/mingling/docs/dev-docs/)
+- 🔍 [Devdoc](https://mingling-rs.github.io/mingling/docs/dev/)
<h1 align="center">
Getting Started
@@ -64,7 +64,7 @@ Add Mingling to your `Cargo.toml`:
```toml
[dependencies.mingling]
-version = "0.2.1"
+version = "0.2.2"
features = []
```
diff --git a/docs/_zh_CN/pages/1-getting-started.md b/docs/_zh_CN/pages/1-getting-started.md
index 0a872c2..6dd1dea 100644
--- a/docs/_zh_CN/pages/1-getting-started.md
+++ b/docs/_zh_CN/pages/1-getting-started.md
@@ -13,7 +13,7 @@ cd my-cli
```toml
[dependencies.mingling]
-version = "0.2.1"
+version = "0.2.2"
features = []
```
@@ -25,7 +25,7 @@ features = []
```toml
[dependencies.mingling]
-version = "0.2.1"
+version = "0.2.2"
features = [
"parser",
"comp",
diff --git a/docs/dev-docs/README.md b/docs/dev-docs/README.md
deleted file mode 100644
index a2eede9..0000000
--- a/docs/dev-docs/README.md
+++ /dev/null
@@ -1,15 +0,0 @@
-<h1 align="center">Mingling Dev Docs</h1>
-
-<p align="center">
- Internal development documentation for the <b>Mingling</b> codebase — design notes, issue discussions, and architectural decisions.
-</p>
-
-This site is separate from the [main helpdoc](https://mingling-rs.github.io/mingling/docs/doc.html). The helpdoc is user-facing: tutorials, feature guides, and how-to content for developers _using_ Mingling to build CLI applications. This dev-docs site is for developers _working on_ Mingling itself — understanding internal mechanisms, tracking unresolved problems, and recording design rationale.
-
-## What's here
-
-- **Issues** — Collected notes on known pain points, unresolved trade-offs, and feature gaps in the current implementation.
-
-## How this is different from GitHub Issues
-
-Mingling is hosted on [GitHub](https://github.com/mingling-rs/mingling), and the [Issues page](https://github.com/mingling-rs/mingling/issues) there is primarily for discussion. In contrast, an issue in this document exists only when it is being planned or actively worked on.
diff --git a/docs/dev-docs/pages/abouts/.name b/docs/dev-docs/pages/abouts/.name
deleted file mode 100644
index d5a4a33..0000000
--- a/docs/dev-docs/pages/abouts/.name
+++ /dev/null
@@ -1 +0,0 @@
-Abouts
diff --git a/docs/dev-docs/pages/issues/.name b/docs/dev-docs/pages/issues/.name
deleted file mode 100644
index f99478d..0000000
--- a/docs/dev-docs/pages/issues/.name
+++ /dev/null
@@ -1 +0,0 @@
-Issues
diff --git a/docs/dev/README.md b/docs/dev/README.md
new file mode 100644
index 0000000..9289fcf
--- /dev/null
+++ b/docs/dev/README.md
@@ -0,0 +1,21 @@
+<h1 align="center">Mingling Dev Docs</h1>
+
+<p align="center">
+ Internal development documentation for the <b>Mingling</b> codebase — design notes, issue discussions, and architectural decisions.
+</p>
+
+This site is separate from the [Helpdoc](https://mingling-rs.github.io/mingling/docs/doc.html).
+
+The helpdoc is user-facing: `tutorials`, `feature guides`, and `how-to content` for developers _using_ Mingling to build CLI applications.
+
+This dev-docs site is for developers **working on** Mingling itself — understanding internal mechanisms, tracking unresolved problems, and recording design rationale.
+
+## What's here
+
+- **Issues** — Collected notes on known pain points, unresolved trade-offs, and feature gaps in the current implementation.
+
+## How this is different from GitHub Issues
+
+Mingling is hosted on [GitHub](https://github.com/mingling-rs/mingling), and the [Issues page](https://github.com/mingling-rs/mingling/issues) there is primarily for discussion.
+
+In contrast, an issue in this document exists only when it is being planned or actively worked on.
diff --git a/docs/dev-docs/_sidebar.md b/docs/dev/_sidebar.md
index acdb46f..5182676 100644
--- a/docs/dev-docs/_sidebar.md
+++ b/docs/dev/_sidebar.md
@@ -1,9 +1,10 @@
- [Welcome!](README)
-* Abouts
- * [AI Translation Rule](pages/abouts/ai-translation-rule)
- * [Markdown Code Verification System](pages/abouts/code-verify-system)
-* Issues
+* ❓ Issues
+ * [Remove r_print! and r_println! Macros](pages/issues/remove-r-print-macro)
* [The Mod Pathfinder](pages/issues/the-mod-pathfinder)
* [Some Situations Where You'd Be Like "Shit!"](pages/issues/the-shit-time)
-* templates
+* 💡 Abouts
+ * [AI Translation Rule](pages/abouts/ai-translation-rule)
+ * [Markdown Code Verification System](pages/abouts/code-verify-system)
+* 📄 Templates
* [Helpdoc Template](pages/templates/doc)
diff --git a/docs/dev-docs/index.html b/docs/dev/index.html
index e62268d..e62268d 100644
--- a/docs/dev-docs/index.html
+++ b/docs/dev/index.html
diff --git a/docs/dev/pages/abouts/.name b/docs/dev/pages/abouts/.name
new file mode 100644
index 0000000..f2b936c
--- /dev/null
+++ b/docs/dev/pages/abouts/.name
@@ -0,0 +1 @@
+💡 Abouts
diff --git a/docs/dev-docs/pages/abouts/ai-translation-rule.md b/docs/dev/pages/abouts/ai-translation-rule.md
index b1f93f6..b1f93f6 100644
--- a/docs/dev-docs/pages/abouts/ai-translation-rule.md
+++ b/docs/dev/pages/abouts/ai-translation-rule.md
diff --git a/docs/dev-docs/pages/abouts/code-verify-system.md b/docs/dev/pages/abouts/code-verify-system.md
index 61b66e8..61b66e8 100644
--- a/docs/dev-docs/pages/abouts/code-verify-system.md
+++ b/docs/dev/pages/abouts/code-verify-system.md
diff --git a/docs/dev/pages/issues/.name b/docs/dev/pages/issues/.name
new file mode 100644
index 0000000..b207fb4
--- /dev/null
+++ b/docs/dev/pages/issues/.name
@@ -0,0 +1 @@
+❓ Issues
diff --git a/docs/dev/pages/issues/remove-r-print-macro.md b/docs/dev/pages/issues/remove-r-print-macro.md
new file mode 100644
index 0000000..96f99ef
--- /dev/null
+++ b/docs/dev/pages/issues/remove-r-print-macro.md
@@ -0,0 +1,97 @@
+<h1 align="center">Remove r_print! and r_println! Macros</h1>
+
+`r_print!` and `r_println!` are important macros in Mingling for use inside `#[help]` and `#[renderer]` functions, but their implementation is not clean: they implicitly introduce a `__renderer_inner_result` field. While this might look elegant at the API level, it is **incorrect** and even **objectionable**.
+
+## Why **Objectionable**?
+
+Because you can't define declarative macros with `macro_rules` that wrap them.
+
+This is because `r_println!` depends on the implicit variable `__renderer_inner_result` injected by the `#[renderer]` proc macro into the function body. However, when a `macro_rules` declarative macro expands, **its internal code is placed in the caller's context**, which does not contain `__renderer_inner_result` — that variable only exists within the direct scope of the function body processed by `#[renderer]`.
+
+Let's look at some code to see why:
+
+```rust
+// Suppose you want to write a wrapper macro:
+macro_rules! my_println {
+ ($($arg:tt)*) => {
+ // When expanded here, the context is the call site of my_println!,
+ // not the location where the renderer function's injected variables live.
+ // So __renderer_inner_result is NOT visible here!
+ r_println!("Custom: {}", format!($($arg)*));
+ };
+}
+
+#[renderer]
+fn render_something(_p: ResultSomething) {
+ // Although this function body has __renderer_inner_result injected,
+ // the code from my_println! does NOT expand "inside this function body" —
+ // macro_rules expansion is essentially text replacement. The replaced code
+ // lives at the line where my_println! is called, and any variables referenced
+ // inside that macro must resolve to identifiers accessible at the call site.
+ // __renderer_inner_result is not a public, path-accessible variable;
+ // it's a hygienic local variable generated by the `#[renderer]` macro,
+ // and external macros cannot directly access it by name.
+ my_println!("{}", box_val); // Compile error: cannot find __renderer_inner_result
+}
+```
+
+## Deeper Issues
+
+I have to admit, this is an early design flaw. After re-examining the code, I found the problem goes beyond "can't be wrapped".
+
+This isn't just a "can't wrap" issue — it reflects that `r_println!`'s design fundamentally violates Rust's macro hygiene principles:
+
+- **Implicit dependency**: Users of the macro must know that a variable named `__renderer_inner_result` exists — but this variable is neither part of the public API nor explicitly documented anywhere.
+- **Scope leakage**: Variables injected by a proc macro should be confined to the scope processed by that macro. But `r_println!` attempts to make that variable accessible across macro calls, which effectively breaks Rust's identifier hygiene.
+- **Non-composable**: Any attempt to wrap `r_println!` will fail, because declarative macros cannot "pass through" access to implicit variables. Even using a proc macro to wrap it would encounter similar hygiene issues.
+
+## Desired New Syntax
+
+I've designed two alternative approaches and will choose based on actual needs.
+
+### Option 1: Explicit Return
+
+```rust
+#[renderer]
+fn render_something(prev: ResultSomething) -> RenderResult {
+ let mut result = RenderResult::new();
+ result.println(prev.to_string());
+ // or
+ write!(result, "{}", prev.to_string());
+
+ result // return here
+}
+```
+
+Clear boundaries — the entire rendering process is confined within the function body decorated by `#[help]` or `#[renderer]`, without introducing extra out-of-scope dependencies. The trade-off is slightly more boilerplate compared to the original approach.
+
+### Option 2: Resource Injection
+
+```rust
+#[renderer]
+fn render_something(prev: ResultSomething, result: &mut ResRenderResult) {
+ result.println(prev.to_string());
+ // or
+ write!(result, "{}", prev.to_string());
+
+ result // return here
+}
+```
+
+More flexible, but blurs the boundary between logic functions like `#[chain]` and rendering functions like `#[help]`.
+
+### Preferred Direction
+
+I lean toward **Option 1 (Explicit Return)**. There's no need to turn `RenderResult` into `ResRenderResult` as a global resource.
+
+As for rendering in logic functions like `#[chain]`, that should be handled by a separate system — not discussed here.
+
+## 🕘 Progress
+
+- [ ] In Progress
+ - [ ] Remove `r_println!` and `r_print!` macros
+ - [ ] Modify `#[renderer]` and `#[help]` macros, remove implicit injection
+ - [ ] Provide **no-return-value mode** and **RenderResult return value mode** for `#[renderer]` and `#[help]` macros
+ - [ ] Add new simplified syntax
+ - [ ] Update documentation and test cases, ensure **all pass**
+- [ ] Complete
diff --git a/docs/dev-docs/pages/issues/the-mod-pathfinder.md b/docs/dev/pages/issues/the-mod-pathfinder.md
index 676251d..676251d 100644
--- a/docs/dev-docs/pages/issues/the-mod-pathfinder.md
+++ b/docs/dev/pages/issues/the-mod-pathfinder.md
diff --git a/docs/dev-docs/pages/issues/the-shit-time.md b/docs/dev/pages/issues/the-shit-time.md
index f524f42..9d6c429 100644
--- a/docs/dev-docs/pages/issues/the-shit-time.md
+++ b/docs/dev/pages/issues/the-shit-time.md
@@ -83,6 +83,16 @@ fn desc_add() -> String {
t!("cmd.add.desc")
}
+// Or
+
+#[completion(CMDAdd)]
+fn desc_add(_ctx: &ShellContext) -> Suggest {
+ // If using rust_i18n
+ suggest{
+ t!("cmd.add.desc")
+ }
+}
+
// Collected and generated by `gen_program!()`
// Generate something like get_dispatcher_desc(id: &ThisProgram) -> String
// Match the corresponding function using enum values inside ThisProgram
diff --git a/docs/dev/pages/templates/.name b/docs/dev/pages/templates/.name
new file mode 100644
index 0000000..9e73889
--- /dev/null
+++ b/docs/dev/pages/templates/.name
@@ -0,0 +1 @@
+📄 Templates
diff --git a/docs/dev-docs/pages/templates/doc.md b/docs/dev/pages/templates/doc.md
index e8a9308..e8a9308 100644
--- a/docs/dev-docs/pages/templates/doc.md
+++ b/docs/dev/pages/templates/doc.md
diff --git a/docs/pages/1-getting-started.md b/docs/pages/1-getting-started.md
index a701d7a..796c6bb 100644
--- a/docs/pages/1-getting-started.md
+++ b/docs/pages/1-getting-started.md
@@ -13,7 +13,7 @@ Add the following to `Cargo.toml`:
```toml
[dependencies.mingling]
-version = "0.2.1"
+version = "0.2.2"
features = []
```
@@ -25,7 +25,7 @@ Some features **directly affect the entire lifecycle behavior**, so you need to
```toml
[dependencies.mingling]
-version = "0.2.1"
+version = "0.2.2"
features = [
"parser",
"comp",
diff --git a/docs/res/guide.txt b/docs/res/guide.txt
index 19d99ff..f0d7652 100644
--- a/docs/res/guide.txt
+++ b/docs/res/guide.txt
@@ -5,5 +5,5 @@
│ > cargo add mingling │
│ │
│ Or add this to your Cargo.toml │
- │ > mingling = "0.2.1" │
+ │ > mingling = "0.2.2" │
└────────────────────────────────────┘
diff --git a/examples/example-argument-parse/Cargo.lock b/examples/example-argument-parse/Cargo.lock
index a2fb6cb..d519d9d 100644
--- a/examples/example-argument-parse/Cargo.lock
+++ b/examples/example-argument-parse/Cargo.lock
@@ -17,7 +17,7 @@ checksum = "5454cda0d57db59778608d7a47bff5b16c6705598265869fb052b657f66cf05e"
[[package]]
name = "mingling"
-version = "0.2.1"
+version = "0.2.2"
dependencies = [
"mingling_core",
"mingling_macros",
@@ -26,18 +26,18 @@ dependencies = [
[[package]]
name = "mingling_core"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c6a8751b43d4fd3d61d7b37f0d7f4d5d274d9391cf80cae9bd75f218219eefe"
+checksum = "b64318a9b61120f0deaf33c4ab9efc9313387dece2defd7841665242807634ea"
dependencies = [
"just_fmt",
]
[[package]]
name = "mingling_macros"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7cd478387797590d2afb4122078649c3e4f9da7f29dbf37817763fecf04958f"
+checksum = "f29efa15f48e39fd4a06868030545b1938e5ba050929cd9a235525814bfb6367"
dependencies = [
"just_fmt",
"proc-macro2",
diff --git a/examples/example-async-support/Cargo.lock b/examples/example-async-support/Cargo.lock
index b5a8a0e..56858e8 100644
--- a/examples/example-async-support/Cargo.lock
+++ b/examples/example-async-support/Cargo.lock
@@ -18,7 +18,7 @@ checksum = "5454cda0d57db59778608d7a47bff5b16c6705598265869fb052b657f66cf05e"
[[package]]
name = "mingling"
-version = "0.2.1"
+version = "0.2.2"
dependencies = [
"mingling_core",
"mingling_macros",
@@ -27,18 +27,18 @@ dependencies = [
[[package]]
name = "mingling_core"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c6a8751b43d4fd3d61d7b37f0d7f4d5d274d9391cf80cae9bd75f218219eefe"
+checksum = "b64318a9b61120f0deaf33c4ab9efc9313387dece2defd7841665242807634ea"
dependencies = [
"just_fmt",
]
[[package]]
name = "mingling_macros"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7cd478387797590d2afb4122078649c3e4f9da7f29dbf37817763fecf04958f"
+checksum = "f29efa15f48e39fd4a06868030545b1938e5ba050929cd9a235525814bfb6367"
dependencies = [
"just_fmt",
"proc-macro2",
diff --git a/examples/example-basic/Cargo.lock b/examples/example-basic/Cargo.lock
index 47ca28e..e8d55bf 100644
--- a/examples/example-basic/Cargo.lock
+++ b/examples/example-basic/Cargo.lock
@@ -17,7 +17,7 @@ checksum = "5454cda0d57db59778608d7a47bff5b16c6705598265869fb052b657f66cf05e"
[[package]]
name = "mingling"
-version = "0.2.1"
+version = "0.2.2"
dependencies = [
"mingling_core",
"mingling_macros",
@@ -25,18 +25,18 @@ dependencies = [
[[package]]
name = "mingling_core"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c6a8751b43d4fd3d61d7b37f0d7f4d5d274d9391cf80cae9bd75f218219eefe"
+checksum = "b64318a9b61120f0deaf33c4ab9efc9313387dece2defd7841665242807634ea"
dependencies = [
"just_fmt",
]
[[package]]
name = "mingling_macros"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7cd478387797590d2afb4122078649c3e4f9da7f29dbf37817763fecf04958f"
+checksum = "f29efa15f48e39fd4a06868030545b1938e5ba050929cd9a235525814bfb6367"
dependencies = [
"just_fmt",
"proc-macro2",
diff --git a/examples/example-clap-binding/Cargo.lock b/examples/example-clap-binding/Cargo.lock
index f08c876..ba7dbc3 100644
--- a/examples/example-clap-binding/Cargo.lock
+++ b/examples/example-clap-binding/Cargo.lock
@@ -126,7 +126,7 @@ checksum = "5454cda0d57db59778608d7a47bff5b16c6705598265869fb052b657f66cf05e"
[[package]]
name = "mingling"
-version = "0.2.1"
+version = "0.2.2"
dependencies = [
"mingling_core",
"mingling_macros",
@@ -134,18 +134,18 @@ dependencies = [
[[package]]
name = "mingling_core"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c6a8751b43d4fd3d61d7b37f0d7f4d5d274d9391cf80cae9bd75f218219eefe"
+checksum = "b64318a9b61120f0deaf33c4ab9efc9313387dece2defd7841665242807634ea"
dependencies = [
"just_fmt",
]
[[package]]
name = "mingling_macros"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7cd478387797590d2afb4122078649c3e4f9da7f29dbf37817763fecf04958f"
+checksum = "f29efa15f48e39fd4a06868030545b1938e5ba050929cd9a235525814bfb6367"
dependencies = [
"just_fmt",
"proc-macro2",
diff --git a/examples/example-combine-pathf-dispatch-tree/Cargo.lock b/examples/example-combine-pathf-dispatch-tree/Cargo.lock
index 8c8288b..8eb1a8f 100644
--- a/examples/example-combine-pathf-dispatch-tree/Cargo.lock
+++ b/examples/example-combine-pathf-dispatch-tree/Cargo.lock
@@ -17,7 +17,7 @@ checksum = "5454cda0d57db59778608d7a47bff5b16c6705598265869fb052b657f66cf05e"
[[package]]
name = "mingling"
-version = "0.2.1"
+version = "0.2.2"
dependencies = [
"mingling_core",
"mingling_macros",
@@ -25,9 +25,9 @@ dependencies = [
[[package]]
name = "mingling_core"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c6a8751b43d4fd3d61d7b37f0d7f4d5d274d9391cf80cae9bd75f218219eefe"
+checksum = "b64318a9b61120f0deaf33c4ab9efc9313387dece2defd7841665242807634ea"
dependencies = [
"just_fmt",
"mingling_pathf",
@@ -35,9 +35,9 @@ dependencies = [
[[package]]
name = "mingling_macros"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7cd478387797590d2afb4122078649c3e4f9da7f29dbf37817763fecf04958f"
+checksum = "f29efa15f48e39fd4a06868030545b1938e5ba050929cd9a235525814bfb6367"
dependencies = [
"just_fmt",
"proc-macro2",
@@ -47,9 +47,9 @@ dependencies = [
[[package]]
name = "mingling_pathf"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9d400d170c80e3f2f7d6f9b6739c286bc64279c805b770fabac390e3a7c7baf0"
+checksum = "134fb0a329f4cc605298eb47683cd2e9eaa184bf651215cbc72d411e9533a4be"
dependencies = [
"just_fmt",
"proc-macro2",
diff --git a/examples/example-completion/Cargo.lock b/examples/example-completion/Cargo.lock
index 658fc8a..7b8bd98 100644
--- a/examples/example-completion/Cargo.lock
+++ b/examples/example-completion/Cargo.lock
@@ -38,7 +38,7 @@ dependencies = [
[[package]]
name = "mingling"
-version = "0.2.1"
+version = "0.2.2"
dependencies = [
"mingling_core",
"mingling_macros",
@@ -47,9 +47,9 @@ dependencies = [
[[package]]
name = "mingling_core"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c6a8751b43d4fd3d61d7b37f0d7f4d5d274d9391cf80cae9bd75f218219eefe"
+checksum = "b64318a9b61120f0deaf33c4ab9efc9313387dece2defd7841665242807634ea"
dependencies = [
"just_fmt",
"just_template",
@@ -57,9 +57,9 @@ dependencies = [
[[package]]
name = "mingling_macros"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7cd478387797590d2afb4122078649c3e4f9da7f29dbf37817763fecf04958f"
+checksum = "f29efa15f48e39fd4a06868030545b1938e5ba050929cd9a235525814bfb6367"
dependencies = [
"just_fmt",
"proc-macro2",
diff --git a/examples/example-custom-pickable/Cargo.lock b/examples/example-custom-pickable/Cargo.lock
index 2d3cfcb..7006ce6 100644
--- a/examples/example-custom-pickable/Cargo.lock
+++ b/examples/example-custom-pickable/Cargo.lock
@@ -17,7 +17,7 @@ checksum = "5454cda0d57db59778608d7a47bff5b16c6705598265869fb052b657f66cf05e"
[[package]]
name = "mingling"
-version = "0.2.1"
+version = "0.2.2"
dependencies = [
"mingling_core",
"mingling_macros",
@@ -26,18 +26,18 @@ dependencies = [
[[package]]
name = "mingling_core"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c6a8751b43d4fd3d61d7b37f0d7f4d5d274d9391cf80cae9bd75f218219eefe"
+checksum = "b64318a9b61120f0deaf33c4ab9efc9313387dece2defd7841665242807634ea"
dependencies = [
"just_fmt",
]
[[package]]
name = "mingling_macros"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7cd478387797590d2afb4122078649c3e4f9da7f29dbf37817763fecf04958f"
+checksum = "f29efa15f48e39fd4a06868030545b1938e5ba050929cd9a235525814bfb6367"
dependencies = [
"just_fmt",
"proc-macro2",
diff --git a/examples/example-dispatch-tree/Cargo.lock b/examples/example-dispatch-tree/Cargo.lock
index 7c530d3..0314dd5 100644
--- a/examples/example-dispatch-tree/Cargo.lock
+++ b/examples/example-dispatch-tree/Cargo.lock
@@ -17,7 +17,7 @@ checksum = "5454cda0d57db59778608d7a47bff5b16c6705598265869fb052b657f66cf05e"
[[package]]
name = "mingling"
-version = "0.2.1"
+version = "0.2.2"
dependencies = [
"mingling_core",
"mingling_macros",
@@ -25,18 +25,18 @@ dependencies = [
[[package]]
name = "mingling_core"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c6a8751b43d4fd3d61d7b37f0d7f4d5d274d9391cf80cae9bd75f218219eefe"
+checksum = "b64318a9b61120f0deaf33c4ab9efc9313387dece2defd7841665242807634ea"
dependencies = [
"just_fmt",
]
[[package]]
name = "mingling_macros"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7cd478387797590d2afb4122078649c3e4f9da7f29dbf37817763fecf04958f"
+checksum = "f29efa15f48e39fd4a06868030545b1938e5ba050929cd9a235525814bfb6367"
dependencies = [
"just_fmt",
"proc-macro2",
diff --git a/examples/example-enum-tag/Cargo.lock b/examples/example-enum-tag/Cargo.lock
index 1d4a6fe..081176b 100644
--- a/examples/example-enum-tag/Cargo.lock
+++ b/examples/example-enum-tag/Cargo.lock
@@ -38,7 +38,7 @@ dependencies = [
[[package]]
name = "mingling"
-version = "0.2.1"
+version = "0.2.2"
dependencies = [
"mingling_core",
"mingling_macros",
@@ -47,9 +47,9 @@ dependencies = [
[[package]]
name = "mingling_core"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c6a8751b43d4fd3d61d7b37f0d7f4d5d274d9391cf80cae9bd75f218219eefe"
+checksum = "b64318a9b61120f0deaf33c4ab9efc9313387dece2defd7841665242807634ea"
dependencies = [
"just_fmt",
"just_template",
@@ -57,9 +57,9 @@ dependencies = [
[[package]]
name = "mingling_macros"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7cd478387797590d2afb4122078649c3e4f9da7f29dbf37817763fecf04958f"
+checksum = "f29efa15f48e39fd4a06868030545b1938e5ba050929cd9a235525814bfb6367"
dependencies = [
"just_fmt",
"proc-macro2",
diff --git a/examples/example-error-handling/Cargo.lock b/examples/example-error-handling/Cargo.lock
index f8424ad..c6effce 100644
--- a/examples/example-error-handling/Cargo.lock
+++ b/examples/example-error-handling/Cargo.lock
@@ -17,7 +17,7 @@ checksum = "5454cda0d57db59778608d7a47bff5b16c6705598265869fb052b657f66cf05e"
[[package]]
name = "mingling"
-version = "0.2.1"
+version = "0.2.2"
dependencies = [
"mingling_core",
"mingling_macros",
@@ -25,18 +25,18 @@ dependencies = [
[[package]]
name = "mingling_core"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c6a8751b43d4fd3d61d7b37f0d7f4d5d274d9391cf80cae9bd75f218219eefe"
+checksum = "b64318a9b61120f0deaf33c4ab9efc9313387dece2defd7841665242807634ea"
dependencies = [
"just_fmt",
]
[[package]]
name = "mingling_macros"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7cd478387797590d2afb4122078649c3e4f9da7f29dbf37817763fecf04958f"
+checksum = "f29efa15f48e39fd4a06868030545b1938e5ba050929cd9a235525814bfb6367"
dependencies = [
"just_fmt",
"proc-macro2",
diff --git a/examples/example-exitcode/Cargo.lock b/examples/example-exitcode/Cargo.lock
index b52bb37..6f3a730 100644
--- a/examples/example-exitcode/Cargo.lock
+++ b/examples/example-exitcode/Cargo.lock
@@ -17,7 +17,7 @@ checksum = "5454cda0d57db59778608d7a47bff5b16c6705598265869fb052b657f66cf05e"
[[package]]
name = "mingling"
-version = "0.2.1"
+version = "0.2.2"
dependencies = [
"mingling_core",
"mingling_macros",
@@ -25,18 +25,18 @@ dependencies = [
[[package]]
name = "mingling_core"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c6a8751b43d4fd3d61d7b37f0d7f4d5d274d9391cf80cae9bd75f218219eefe"
+checksum = "b64318a9b61120f0deaf33c4ab9efc9313387dece2defd7841665242807634ea"
dependencies = [
"just_fmt",
]
[[package]]
name = "mingling_macros"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7cd478387797590d2afb4122078649c3e4f9da7f29dbf37817763fecf04958f"
+checksum = "f29efa15f48e39fd4a06868030545b1938e5ba050929cd9a235525814bfb6367"
dependencies = [
"just_fmt",
"proc-macro2",
diff --git a/examples/example-help/Cargo.lock b/examples/example-help/Cargo.lock
index 0f127d7..8c3fb07 100644
--- a/examples/example-help/Cargo.lock
+++ b/examples/example-help/Cargo.lock
@@ -17,7 +17,7 @@ checksum = "5454cda0d57db59778608d7a47bff5b16c6705598265869fb052b657f66cf05e"
[[package]]
name = "mingling"
-version = "0.2.1"
+version = "0.2.2"
dependencies = [
"mingling_core",
"mingling_macros",
@@ -25,18 +25,18 @@ dependencies = [
[[package]]
name = "mingling_core"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c6a8751b43d4fd3d61d7b37f0d7f4d5d274d9391cf80cae9bd75f218219eefe"
+checksum = "b64318a9b61120f0deaf33c4ab9efc9313387dece2defd7841665242807634ea"
dependencies = [
"just_fmt",
]
[[package]]
name = "mingling_macros"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7cd478387797590d2afb4122078649c3e4f9da7f29dbf37817763fecf04958f"
+checksum = "f29efa15f48e39fd4a06868030545b1938e5ba050929cd9a235525814bfb6367"
dependencies = [
"just_fmt",
"proc-macro2",
diff --git a/examples/example-hook/Cargo.lock b/examples/example-hook/Cargo.lock
index 6dc2a58..e83ec75 100644
--- a/examples/example-hook/Cargo.lock
+++ b/examples/example-hook/Cargo.lock
@@ -17,7 +17,7 @@ checksum = "5454cda0d57db59778608d7a47bff5b16c6705598265869fb052b657f66cf05e"
[[package]]
name = "mingling"
-version = "0.2.1"
+version = "0.2.2"
dependencies = [
"mingling_core",
"mingling_macros",
@@ -25,18 +25,18 @@ dependencies = [
[[package]]
name = "mingling_core"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c6a8751b43d4fd3d61d7b37f0d7f4d5d274d9391cf80cae9bd75f218219eefe"
+checksum = "b64318a9b61120f0deaf33c4ab9efc9313387dece2defd7841665242807634ea"
dependencies = [
"just_fmt",
]
[[package]]
name = "mingling_macros"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7cd478387797590d2afb4122078649c3e4f9da7f29dbf37817763fecf04958f"
+checksum = "f29efa15f48e39fd4a06868030545b1938e5ba050929cd9a235525814bfb6367"
dependencies = [
"just_fmt",
"proc-macro2",
diff --git a/examples/example-implicit-dispatcher/Cargo.lock b/examples/example-implicit-dispatcher/Cargo.lock
index 930c7a1..f368597 100644
--- a/examples/example-implicit-dispatcher/Cargo.lock
+++ b/examples/example-implicit-dispatcher/Cargo.lock
@@ -17,7 +17,7 @@ checksum = "5454cda0d57db59778608d7a47bff5b16c6705598265869fb052b657f66cf05e"
[[package]]
name = "mingling"
-version = "0.2.1"
+version = "0.2.2"
dependencies = [
"mingling_core",
"mingling_macros",
@@ -25,18 +25,18 @@ dependencies = [
[[package]]
name = "mingling_core"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c6a8751b43d4fd3d61d7b37f0d7f4d5d274d9391cf80cae9bd75f218219eefe"
+checksum = "b64318a9b61120f0deaf33c4ab9efc9313387dece2defd7841665242807634ea"
dependencies = [
"just_fmt",
]
[[package]]
name = "mingling_macros"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7cd478387797590d2afb4122078649c3e4f9da7f29dbf37817763fecf04958f"
+checksum = "f29efa15f48e39fd4a06868030545b1938e5ba050929cd9a235525814bfb6367"
dependencies = [
"just_fmt",
"proc-macro2",
diff --git a/examples/example-lazy-resources/Cargo.lock b/examples/example-lazy-resources/Cargo.lock
index 4df7212..342ebcb 100644
--- a/examples/example-lazy-resources/Cargo.lock
+++ b/examples/example-lazy-resources/Cargo.lock
@@ -17,7 +17,7 @@ checksum = "5454cda0d57db59778608d7a47bff5b16c6705598265869fb052b657f66cf05e"
[[package]]
name = "mingling"
-version = "0.2.1"
+version = "0.2.2"
dependencies = [
"mingling_core",
"mingling_macros",
@@ -25,18 +25,18 @@ dependencies = [
[[package]]
name = "mingling_core"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c6a8751b43d4fd3d61d7b37f0d7f4d5d274d9391cf80cae9bd75f218219eefe"
+checksum = "b64318a9b61120f0deaf33c4ab9efc9313387dece2defd7841665242807634ea"
dependencies = [
"just_fmt",
]
[[package]]
name = "mingling_macros"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7cd478387797590d2afb4122078649c3e4f9da7f29dbf37817763fecf04958f"
+checksum = "f29efa15f48e39fd4a06868030545b1938e5ba050929cd9a235525814bfb6367"
dependencies = [
"just_fmt",
"proc-macro2",
diff --git a/examples/example-outside-type/Cargo.lock b/examples/example-outside-type/Cargo.lock
index 98bc63d..240a444 100644
--- a/examples/example-outside-type/Cargo.lock
+++ b/examples/example-outside-type/Cargo.lock
@@ -17,7 +17,7 @@ checksum = "5454cda0d57db59778608d7a47bff5b16c6705598265869fb052b657f66cf05e"
[[package]]
name = "mingling"
-version = "0.2.1"
+version = "0.2.2"
dependencies = [
"mingling_core",
"mingling_macros",
@@ -25,18 +25,18 @@ dependencies = [
[[package]]
name = "mingling_core"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c6a8751b43d4fd3d61d7b37f0d7f4d5d274d9391cf80cae9bd75f218219eefe"
+checksum = "b64318a9b61120f0deaf33c4ab9efc9313387dece2defd7841665242807634ea"
dependencies = [
"just_fmt",
]
[[package]]
name = "mingling_macros"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7cd478387797590d2afb4122078649c3e4f9da7f29dbf37817763fecf04958f"
+checksum = "f29efa15f48e39fd4a06868030545b1938e5ba050929cd9a235525814bfb6367"
dependencies = [
"just_fmt",
"proc-macro2",
diff --git a/examples/example-pack-err/Cargo.lock b/examples/example-pack-err/Cargo.lock
index 0447a39..0776937 100644
--- a/examples/example-pack-err/Cargo.lock
+++ b/examples/example-pack-err/Cargo.lock
@@ -30,7 +30,7 @@ checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4"
[[package]]
name = "mingling"
-version = "0.2.1"
+version = "0.2.2"
dependencies = [
"mingling_core",
"mingling_macros",
@@ -39,9 +39,9 @@ dependencies = [
[[package]]
name = "mingling_core"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c6a8751b43d4fd3d61d7b37f0d7f4d5d274d9391cf80cae9bd75f218219eefe"
+checksum = "b64318a9b61120f0deaf33c4ab9efc9313387dece2defd7841665242807634ea"
dependencies = [
"just_fmt",
"serde",
@@ -50,9 +50,9 @@ dependencies = [
[[package]]
name = "mingling_macros"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7cd478387797590d2afb4122078649c3e4f9da7f29dbf37817763fecf04958f"
+checksum = "f29efa15f48e39fd4a06868030545b1938e5ba050929cd9a235525814bfb6367"
dependencies = [
"just_fmt",
"proc-macro2",
diff --git a/examples/example-panic-unwind/Cargo.lock b/examples/example-panic-unwind/Cargo.lock
index 2cb07f0..c453b54 100644
--- a/examples/example-panic-unwind/Cargo.lock
+++ b/examples/example-panic-unwind/Cargo.lock
@@ -17,7 +17,7 @@ checksum = "5454cda0d57db59778608d7a47bff5b16c6705598265869fb052b657f66cf05e"
[[package]]
name = "mingling"
-version = "0.2.1"
+version = "0.2.2"
dependencies = [
"mingling_core",
"mingling_macros",
@@ -26,18 +26,18 @@ dependencies = [
[[package]]
name = "mingling_core"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c6a8751b43d4fd3d61d7b37f0d7f4d5d274d9391cf80cae9bd75f218219eefe"
+checksum = "b64318a9b61120f0deaf33c4ab9efc9313387dece2defd7841665242807634ea"
dependencies = [
"just_fmt",
]
[[package]]
name = "mingling_macros"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7cd478387797590d2afb4122078649c3e4f9da7f29dbf37817763fecf04958f"
+checksum = "f29efa15f48e39fd4a06868030545b1938e5ba050929cd9a235525814bfb6367"
dependencies = [
"just_fmt",
"proc-macro2",
diff --git a/examples/example-pathfinder/Cargo.lock b/examples/example-pathfinder/Cargo.lock
index 11eccce..f1d7564 100644
--- a/examples/example-pathfinder/Cargo.lock
+++ b/examples/example-pathfinder/Cargo.lock
@@ -17,7 +17,7 @@ checksum = "5454cda0d57db59778608d7a47bff5b16c6705598265869fb052b657f66cf05e"
[[package]]
name = "mingling"
-version = "0.2.1"
+version = "0.2.2"
dependencies = [
"mingling_core",
"mingling_macros",
@@ -25,9 +25,9 @@ dependencies = [
[[package]]
name = "mingling_core"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c6a8751b43d4fd3d61d7b37f0d7f4d5d274d9391cf80cae9bd75f218219eefe"
+checksum = "b64318a9b61120f0deaf33c4ab9efc9313387dece2defd7841665242807634ea"
dependencies = [
"just_fmt",
"mingling_pathf",
@@ -35,9 +35,9 @@ dependencies = [
[[package]]
name = "mingling_macros"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7cd478387797590d2afb4122078649c3e4f9da7f29dbf37817763fecf04958f"
+checksum = "f29efa15f48e39fd4a06868030545b1938e5ba050929cd9a235525814bfb6367"
dependencies = [
"just_fmt",
"proc-macro2",
@@ -47,9 +47,9 @@ dependencies = [
[[package]]
name = "mingling_pathf"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9d400d170c80e3f2f7d6f9b6739c286bc64279c805b770fabac390e3a7c7baf0"
+checksum = "134fb0a329f4cc605298eb47683cd2e9eaa184bf651215cbc72d411e9533a4be"
dependencies = [
"just_fmt",
"proc-macro2",
diff --git a/examples/example-repl-basic/Cargo.lock b/examples/example-repl-basic/Cargo.lock
index bfb2bb3..ad07dc6 100644
--- a/examples/example-repl-basic/Cargo.lock
+++ b/examples/example-repl-basic/Cargo.lock
@@ -18,7 +18,7 @@ checksum = "5454cda0d57db59778608d7a47bff5b16c6705598265869fb052b657f66cf05e"
[[package]]
name = "mingling"
-version = "0.2.1"
+version = "0.2.2"
dependencies = [
"mingling_core",
"mingling_macros",
@@ -27,18 +27,18 @@ dependencies = [
[[package]]
name = "mingling_core"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c6a8751b43d4fd3d61d7b37f0d7f4d5d274d9391cf80cae9bd75f218219eefe"
+checksum = "b64318a9b61120f0deaf33c4ab9efc9313387dece2defd7841665242807634ea"
dependencies = [
"just_fmt",
]
[[package]]
name = "mingling_macros"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7cd478387797590d2afb4122078649c3e4f9da7f29dbf37817763fecf04958f"
+checksum = "f29efa15f48e39fd4a06868030545b1938e5ba050929cd9a235525814bfb6367"
dependencies = [
"just_fmt",
"proc-macro2",
diff --git a/examples/example-resources/Cargo.lock b/examples/example-resources/Cargo.lock
index ff153f2..f16f414 100644
--- a/examples/example-resources/Cargo.lock
+++ b/examples/example-resources/Cargo.lock
@@ -17,7 +17,7 @@ checksum = "5454cda0d57db59778608d7a47bff5b16c6705598265869fb052b657f66cf05e"
[[package]]
name = "mingling"
-version = "0.2.1"
+version = "0.2.2"
dependencies = [
"mingling_core",
"mingling_macros",
@@ -26,18 +26,18 @@ dependencies = [
[[package]]
name = "mingling_core"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c6a8751b43d4fd3d61d7b37f0d7f4d5d274d9391cf80cae9bd75f218219eefe"
+checksum = "b64318a9b61120f0deaf33c4ab9efc9313387dece2defd7841665242807634ea"
dependencies = [
"just_fmt",
]
[[package]]
name = "mingling_macros"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7cd478387797590d2afb4122078649c3e4f9da7f29dbf37817763fecf04958f"
+checksum = "f29efa15f48e39fd4a06868030545b1938e5ba050929cd9a235525814bfb6367"
dependencies = [
"just_fmt",
"proc-macro2",
diff --git a/examples/example-setup/Cargo.lock b/examples/example-setup/Cargo.lock
index e89dee8..5b7805b 100644
--- a/examples/example-setup/Cargo.lock
+++ b/examples/example-setup/Cargo.lock
@@ -17,7 +17,7 @@ checksum = "5454cda0d57db59778608d7a47bff5b16c6705598265869fb052b657f66cf05e"
[[package]]
name = "mingling"
-version = "0.2.1"
+version = "0.2.2"
dependencies = [
"mingling_core",
"mingling_macros",
@@ -25,18 +25,18 @@ dependencies = [
[[package]]
name = "mingling_core"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c6a8751b43d4fd3d61d7b37f0d7f4d5d274d9391cf80cae9bd75f218219eefe"
+checksum = "b64318a9b61120f0deaf33c4ab9efc9313387dece2defd7841665242807634ea"
dependencies = [
"just_fmt",
]
[[package]]
name = "mingling_macros"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7cd478387797590d2afb4122078649c3e4f9da7f29dbf37817763fecf04958f"
+checksum = "f29efa15f48e39fd4a06868030545b1938e5ba050929cd9a235525814bfb6367"
dependencies = [
"just_fmt",
"proc-macro2",
diff --git a/examples/example-structural-renderer/Cargo.lock b/examples/example-structural-renderer/Cargo.lock
index 43e8688..349a92f 100644
--- a/examples/example-structural-renderer/Cargo.lock
+++ b/examples/example-structural-renderer/Cargo.lock
@@ -30,7 +30,7 @@ checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4"
[[package]]
name = "mingling"
-version = "0.2.1"
+version = "0.2.2"
dependencies = [
"mingling_core",
"mingling_macros",
@@ -40,9 +40,9 @@ dependencies = [
[[package]]
name = "mingling_core"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c6a8751b43d4fd3d61d7b37f0d7f4d5d274d9391cf80cae9bd75f218219eefe"
+checksum = "b64318a9b61120f0deaf33c4ab9efc9313387dece2defd7841665242807634ea"
dependencies = [
"just_fmt",
"serde",
@@ -51,9 +51,9 @@ dependencies = [
[[package]]
name = "mingling_macros"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7cd478387797590d2afb4122078649c3e4f9da7f29dbf37817763fecf04958f"
+checksum = "f29efa15f48e39fd4a06868030545b1938e5ba050929cd9a235525814bfb6367"
dependencies = [
"just_fmt",
"proc-macro2",
diff --git a/examples/example-unit-test/Cargo.lock b/examples/example-unit-test/Cargo.lock
index 968f3e0..8ec0ab7 100644
--- a/examples/example-unit-test/Cargo.lock
+++ b/examples/example-unit-test/Cargo.lock
@@ -17,7 +17,7 @@ checksum = "5454cda0d57db59778608d7a47bff5b16c6705598265869fb052b657f66cf05e"
[[package]]
name = "mingling"
-version = "0.2.1"
+version = "0.2.2"
dependencies = [
"mingling_core",
"mingling_macros",
@@ -25,18 +25,18 @@ dependencies = [
[[package]]
name = "mingling_core"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c6a8751b43d4fd3d61d7b37f0d7f4d5d274d9391cf80cae9bd75f218219eefe"
+checksum = "b64318a9b61120f0deaf33c4ab9efc9313387dece2defd7841665242807634ea"
dependencies = [
"just_fmt",
]
[[package]]
name = "mingling_macros"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7cd478387797590d2afb4122078649c3e4f9da7f29dbf37817763fecf04958f"
+checksum = "f29efa15f48e39fd4a06868030545b1938e5ba050929cd9a235525814bfb6367"
dependencies = [
"just_fmt",
"proc-macro2",
diff --git a/examples/full-todolist/Cargo.lock b/examples/full-todolist/Cargo.lock
index aa515bf..f46c5ad 100644
--- a/examples/full-todolist/Cargo.lock
+++ b/examples/full-todolist/Cargo.lock
@@ -31,7 +31,7 @@ checksum = "6b947ae49db0d222b1dbc6b113ce7248a3fc3a6ca21b696717bfc000ba4484d8"
[[package]]
name = "mingling"
-version = "0.2.1"
+version = "0.2.2"
dependencies = [
"mingling_core",
"mingling_macros",
@@ -41,9 +41,9 @@ dependencies = [
[[package]]
name = "mingling_core"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c6a8751b43d4fd3d61d7b37f0d7f4d5d274d9391cf80cae9bd75f218219eefe"
+checksum = "b64318a9b61120f0deaf33c4ab9efc9313387dece2defd7841665242807634ea"
dependencies = [
"just_fmt",
"serde",
@@ -52,9 +52,9 @@ dependencies = [
[[package]]
name = "mingling_macros"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7cd478387797590d2afb4122078649c3e4f9da7f29dbf37817763fecf04958f"
+checksum = "f29efa15f48e39fd4a06868030545b1938e5ba050929cd9a235525814bfb6367"
dependencies = [
"just_fmt",
"proc-macro2",
diff --git a/mingling_core/tests/test-all/Cargo.lock b/mingling_core/tests/test-all/Cargo.lock
index 815076a..d18eb47 100644
--- a/mingling_core/tests/test-all/Cargo.lock
+++ b/mingling_core/tests/test-all/Cargo.lock
@@ -111,7 +111,7 @@ checksum = "6b947ae49db0d222b1dbc6b113ce7248a3fc3a6ca21b696717bfc000ba4484d8"
[[package]]
name = "mingling"
-version = "0.2.1"
+version = "0.2.2"
dependencies = [
"mingling_core",
"mingling_macros",
@@ -121,9 +121,9 @@ dependencies = [
[[package]]
name = "mingling_core"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c6a8751b43d4fd3d61d7b37f0d7f4d5d274d9391cf80cae9bd75f218219eefe"
+checksum = "b64318a9b61120f0deaf33c4ab9efc9313387dece2defd7841665242807634ea"
dependencies = [
"just_fmt",
"just_template",
@@ -136,9 +136,9 @@ dependencies = [
[[package]]
name = "mingling_macros"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7cd478387797590d2afb4122078649c3e4f9da7f29dbf37817763fecf04958f"
+checksum = "f29efa15f48e39fd4a06868030545b1938e5ba050929cd9a235525814bfb6367"
dependencies = [
"just_fmt",
"proc-macro2",
diff --git a/mingling_core/tests/test-basic/Cargo.lock b/mingling_core/tests/test-basic/Cargo.lock
index 597eb16..ef023a7 100644
--- a/mingling_core/tests/test-basic/Cargo.lock
+++ b/mingling_core/tests/test-basic/Cargo.lock
@@ -10,7 +10,7 @@ checksum = "5454cda0d57db59778608d7a47bff5b16c6705598265869fb052b657f66cf05e"
[[package]]
name = "mingling"
-version = "0.2.1"
+version = "0.2.2"
dependencies = [
"mingling_core",
"mingling_macros",
@@ -18,18 +18,18 @@ dependencies = [
[[package]]
name = "mingling_core"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c6a8751b43d4fd3d61d7b37f0d7f4d5d274d9391cf80cae9bd75f218219eefe"
+checksum = "b64318a9b61120f0deaf33c4ab9efc9313387dece2defd7841665242807634ea"
dependencies = [
"just_fmt",
]
[[package]]
name = "mingling_macros"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7cd478387797590d2afb4122078649c3e4f9da7f29dbf37817763fecf04958f"
+checksum = "f29efa15f48e39fd4a06868030545b1938e5ba050929cd9a235525814bfb6367"
dependencies = [
"just_fmt",
"proc-macro2",
diff --git a/mingling_core/tests/test-comp/Cargo.lock b/mingling_core/tests/test-comp/Cargo.lock
index fed185b..b951a91 100644
--- a/mingling_core/tests/test-comp/Cargo.lock
+++ b/mingling_core/tests/test-comp/Cargo.lock
@@ -31,7 +31,7 @@ dependencies = [
[[package]]
name = "mingling"
-version = "0.2.1"
+version = "0.2.2"
dependencies = [
"mingling_core",
"mingling_macros",
@@ -39,9 +39,9 @@ dependencies = [
[[package]]
name = "mingling_core"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c6a8751b43d4fd3d61d7b37f0d7f4d5d274d9391cf80cae9bd75f218219eefe"
+checksum = "b64318a9b61120f0deaf33c4ab9efc9313387dece2defd7841665242807634ea"
dependencies = [
"just_fmt",
"just_template",
@@ -49,9 +49,9 @@ dependencies = [
[[package]]
name = "mingling_macros"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7cd478387797590d2afb4122078649c3e4f9da7f29dbf37817763fecf04958f"
+checksum = "f29efa15f48e39fd4a06868030545b1938e5ba050929cd9a235525814bfb6367"
dependencies = [
"just_fmt",
"proc-macro2",
diff --git a/mingling_core/tests/test-dispatch-tree/Cargo.lock b/mingling_core/tests/test-dispatch-tree/Cargo.lock
index 64aeff5..14027ae 100644
--- a/mingling_core/tests/test-dispatch-tree/Cargo.lock
+++ b/mingling_core/tests/test-dispatch-tree/Cargo.lock
@@ -10,7 +10,7 @@ checksum = "5454cda0d57db59778608d7a47bff5b16c6705598265869fb052b657f66cf05e"
[[package]]
name = "mingling"
-version = "0.2.1"
+version = "0.2.2"
dependencies = [
"mingling_core",
"mingling_macros",
@@ -18,18 +18,18 @@ dependencies = [
[[package]]
name = "mingling_core"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c6a8751b43d4fd3d61d7b37f0d7f4d5d274d9391cf80cae9bd75f218219eefe"
+checksum = "b64318a9b61120f0deaf33c4ab9efc9313387dece2defd7841665242807634ea"
dependencies = [
"just_fmt",
]
[[package]]
name = "mingling_macros"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7cd478387797590d2afb4122078649c3e4f9da7f29dbf37817763fecf04958f"
+checksum = "f29efa15f48e39fd4a06868030545b1938e5ba050929cd9a235525814bfb6367"
dependencies = [
"just_fmt",
"proc-macro2",
diff --git a/mingling_core/tests/test-repl/Cargo.lock b/mingling_core/tests/test-repl/Cargo.lock
index e15acd0..b811703 100644
--- a/mingling_core/tests/test-repl/Cargo.lock
+++ b/mingling_core/tests/test-repl/Cargo.lock
@@ -10,7 +10,7 @@ checksum = "5454cda0d57db59778608d7a47bff5b16c6705598265869fb052b657f66cf05e"
[[package]]
name = "mingling"
-version = "0.2.1"
+version = "0.2.2"
dependencies = [
"mingling_core",
"mingling_macros",
@@ -18,18 +18,18 @@ dependencies = [
[[package]]
name = "mingling_core"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c6a8751b43d4fd3d61d7b37f0d7f4d5d274d9391cf80cae9bd75f218219eefe"
+checksum = "b64318a9b61120f0deaf33c4ab9efc9313387dece2defd7841665242807634ea"
dependencies = [
"just_fmt",
]
[[package]]
name = "mingling_macros"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7cd478387797590d2afb4122078649c3e4f9da7f29dbf37817763fecf04958f"
+checksum = "f29efa15f48e39fd4a06868030545b1938e5ba050929cd9a235525814bfb6367"
dependencies = [
"just_fmt",
"proc-macro2",
diff --git a/mingling_core/tests/test-structural-renderer/Cargo.lock b/mingling_core/tests/test-structural-renderer/Cargo.lock
index 9d9738b..962d2d4 100644
--- a/mingling_core/tests/test-structural-renderer/Cargo.lock
+++ b/mingling_core/tests/test-structural-renderer/Cargo.lock
@@ -53,7 +53,7 @@ checksum = "6b947ae49db0d222b1dbc6b113ce7248a3fc3a6ca21b696717bfc000ba4484d8"
[[package]]
name = "mingling"
-version = "0.2.1"
+version = "0.2.2"
dependencies = [
"mingling_core",
"mingling_macros",
@@ -63,9 +63,9 @@ dependencies = [
[[package]]
name = "mingling_core"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c6a8751b43d4fd3d61d7b37f0d7f4d5d274d9391cf80cae9bd75f218219eefe"
+checksum = "b64318a9b61120f0deaf33c4ab9efc9313387dece2defd7841665242807634ea"
dependencies = [
"just_fmt",
"ron",
@@ -77,9 +77,9 @@ dependencies = [
[[package]]
name = "mingling_macros"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7cd478387797590d2afb4122078649c3e4f9da7f29dbf37817763fecf04958f"
+checksum = "f29efa15f48e39fd4a06868030545b1938e5ba050929cd9a235525814bfb6367"
dependencies = [
"just_fmt",
"proc-macro2",
diff --git a/mingling_macros/src/structural_data.rs b/mingling_macros/src/structural_data.rs
index d556d8c..5350d7e 100644
--- a/mingling_macros/src/structural_data.rs
+++ b/mingling_macros/src/structural_data.rs
@@ -268,11 +268,18 @@ pub(crate) fn group_structural(input: TokenStream) -> TokenStream {
proc_macro2::Span::call_site(),
);
- // Generate the appropriate `use` statement
+ // Generate the appropriate `use` statement for the original type
+ // (consistent with gen_type_use in group_impl.rs)
let type_use = if type_path.path.segments.len() > 1 {
quote! { #[allow(unused_imports)] use #type_path; }
} else {
- let ident = &type_name;
+ let ident = type_path
+ .path
+ .segments
+ .last()
+ .expect("TypePath must have at least one segment")
+ .ident
+ .clone();
quote! { #[allow(unused_imports)] use super::#ident; }
};
diff --git a/mingling_pathf/test/Cargo.lock b/mingling_pathf/test/Cargo.lock
index ab0a711..92b0bda 100644
--- a/mingling_pathf/test/Cargo.lock
+++ b/mingling_pathf/test/Cargo.lock
@@ -10,7 +10,7 @@ checksum = "5454cda0d57db59778608d7a47bff5b16c6705598265869fb052b657f66cf05e"
[[package]]
name = "mingling_pathf"
-version = "0.2.1"
+version = "0.2.2"
dependencies = [
"just_fmt",
"proc-macro2",
diff --git a/docs/dev-docs/pages/templates/.name b/mling/res/template_0.2/command/Cargo.toml.tmpl
index e69de29..e69de29 100644
--- a/docs/dev-docs/pages/templates/.name
+++ b/mling/res/template_0.2/command/Cargo.toml.tmpl
diff --git a/mling/res/template_0.2/command/Cargo.toml b/mling/res/template_0.2/flat/Cargo.toml.tmpl
index e69de29..e69de29 100644
--- a/mling/res/template_0.2/command/Cargo.toml
+++ b/mling/res/template_0.2/flat/Cargo.toml.tmpl
diff --git a/mling/res/template_0.2/modularity/Cargo.toml b/mling/res/template_0.2/modularity/Cargo.toml
deleted file mode 100644
index e69de29..0000000
--- a/mling/res/template_0.2/modularity/Cargo.toml
+++ /dev/null
diff --git a/mling/res/template_0.2/flat/Cargo.toml b/mling/res/template_0.2/modularity/Cargo.toml.tmpl
index e69de29..e69de29 100644
--- a/mling/res/template_0.2/flat/Cargo.toml
+++ b/mling/res/template_0.2/modularity/Cargo.toml.tmpl
diff --git a/run-tools.ps1 b/run-tools.ps1
deleted file mode 100644
index 7aa2c9c..0000000
--- a/run-tools.ps1
+++ /dev/null
@@ -1,60 +0,0 @@
-Set-Location -Path (Split-Path -Parent $MyInvocation.MyCommand.Path) -ErrorAction Stop
-
-# Collect all available tool names
-$tools = @()
-
-if (Test-Path "dev_tools/scripts") {
- $scripts = Get-ChildItem -Path "dev_tools/scripts/*.ps1", "dev_tools/scripts/*.py"
- foreach ($script in $scripts) {
- if ($script -is [System.IO.FileInfo]) {
- $tools += $script.BaseName
- }
- }
-}
-if (Test-Path "dev_tools/src/bin") {
- $files = Get-ChildItem -Path "dev_tools/src/bin/*.rs"
- foreach ($file in $files) {
- if ($file -is [System.IO.FileInfo]) {
- $tools += $file.BaseName
- }
- }
-}
-
-if ($args.Count -eq 0) {
- Write-Host "Available:"
- for ($i = 0; $i -lt $tools.Count; $i++) {
- Write-Host (" [{0,2}] {1}" -f ($i + 1), $tools[$i])
- }
- exit 1
-}
-
-$target_name = $args[0]
-
-# Check if input is a number
-if ($target_name -match '^\d+$') {
- $idx = [int]$target_name - 1
- if ($idx -ge 0 -and $idx -lt $tools.Count) {
- $target_name = $tools[$idx]
- } else {
- Write-Host "Error: invalid number '$target_name', valid range is 1-$($tools.Count)"
- exit 1
- }
-}
-
-# Collect remaining arguments to pass to the script
-$script_args = $args[1..$args.Count]
-
-$script_file_ps1 = "dev_tools/scripts/${target_name}.ps1"
-$script_file_py = "dev_tools/scripts/${target_name}.py"
-$rust_file = "dev_tools/src/bin/${target_name}.rs"
-
-if (Test-Path $script_file_ps1) {
- & $script_file_ps1 $script_args
-} elseif (Test-Path $script_file_py) {
- python $script_file_py $script_args
-} elseif (Test-Path $rust_file) {
- cargo run --manifest-path dev_tools/Cargo.toml --bin $target_name --quiet -- $script_args
-} else {
- Write-Host "Error: target '$target_name' does not exist as a script or Rust program"
- exit 1
-}
diff --git a/run-tools.sh b/run-tools.sh
deleted file mode 100755
index 9a68f0e..0000000
--- a/run-tools.sh
+++ /dev/null
@@ -1,64 +0,0 @@
-#!/bin/bash
-
-cd "$(dirname "$0")" || exit 1
-
-# Collect all available tool names
-tools=()
-
-if [ -d "dev_tools/scripts" ]; then
- for file in dev_tools/scripts/*.sh; do
- if [ -f "$file" ]; then
- tools+=("$(basename "$file" .sh)")
- fi
- done
- for file in dev_tools/scripts/*.py; do
- if [ -f "$file" ]; then
- tools+=("$(basename "$file" .py)")
- fi
- done
-fi
-if [ -d "dev_tools/src/bin" ]; then
- for file in dev_tools/src/bin/*.rs; do
- if [ -f "$file" ]; then
- tools+=("$(basename "$file" .rs)")
- fi
- done
-fi
-
-if [ $# -eq 0 ]; then
- echo "Available:"
- for i in "${!tools[@]}"; do
- printf " [%2d] %s\n" $((i + 1)) "${tools[$i]}"
- done
- exit 1
-fi
-
-target_bin="$1"
-shift # Remove the first argument (tool name), keep the rest as tool arguments
-
-# Check if input is a number
-if [[ "$target_bin" =~ ^[0-9]+$ ]]; then
- idx=$((target_bin - 1))
- if [ "$idx" -ge 0 ] && [ "$idx" -lt "${#tools[@]}" ]; then
- target_bin="${tools[$idx]}"
- else
- echo "Error: invalid number '$target_bin', valid range is 1-${#tools[@]}"
- exit 1
- fi
-fi
-
-target_script="dev_tools/scripts/${target_bin}.sh"
-target_python="dev_tools/scripts/${target_bin}.py"
-target_file="dev_tools/src/bin/${target_bin}.rs"
-
-if [ -f "$target_script" ]; then
- chmod +x "$target_script"
- "$target_script" "$@"
-elif [ -f "$target_python" ]; then
- python "$target_python" "$@"
-elif [ -f "$target_file" ]; then
- cargo run --manifest-path dev_tools/Cargo.toml --bin "$target_bin" --quiet -- "$@"
-else
- echo "Error: target '$target_bin' does not exist"
- exit 1
-fi
diff --git a/run.ps1 b/run.ps1
new file mode 100644
index 0000000..af8effe
--- /dev/null
+++ b/run.ps1
@@ -0,0 +1,232 @@
+#
+# ██ ██████ ██ ██ ███ ██ ██████ ███████ ██
+# ██ ██ ██ ██ ██ ████ ██ ██ ██ ██ ███
+# ██ ██████ ██ ██ ██ ██ ██ ██████ ███████ ██
+# ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
+# ██ ██ ██ ██ ██████ ██ ████ ██ ██ ███████ ██
+#
+# You can go to [https://catilgrass.github.io/run] to install it
+# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Set-Location -Path (Split-Path -Parent $MyInvocation.MyCommand.Path) -ErrorAction Stop
+
+$tools = @{}
+
+if (Test-Path ".run/src/bin/*.ps1") {
+ Get-ChildItem -Path ".run/src/bin/*.ps1" | ForEach-Object {
+ $tools[$_.BaseName] = @{ Type = "ps1"; Path = $_.FullName }
+ }
+}
+
+if (Test-Path ".run/src/bin/*.cs") {
+ Get-ChildItem -Path ".run/src/bin/*.cs" | ForEach-Object {
+ $tools[$_.BaseName] = @{ Type = "cs"; Path = $_.FullName }
+ }
+}
+
+if (Test-Path ".run/src/bin/*.exe") {
+ Get-ChildItem -Path ".run/src/bin/*.exe" | ForEach-Object {
+ $tools[$_.BaseName] = @{ Type = "exe"; Path = $_.FullName }
+ }
+}
+
+if (Test-Path ".run/src/bin/*.go") {
+ Get-ChildItem -Path ".run/src/bin/*.go" | ForEach-Object {
+ $tools[$_.BaseName] = @{ Type = "go"; Path = $_.FullName }
+ }
+}
+
+if (Test-Path ".run/src/bin/*.nim") {
+ Get-ChildItem -Path ".run/src/bin/*.nim" | ForEach-Object {
+ $tools[$_.BaseName] = @{ Type = "nim"; Path = $_.FullName }
+ }
+}
+
+if (Test-Path ".run/src/bin/*.pl") {
+ Get-ChildItem -Path ".run/src/bin/*.pl" | ForEach-Object {
+ $tools[$_.BaseName] = @{ Type = "pl"; Path = $_.FullName }
+ }
+}
+
+if (Test-Path ".run/src/bin/*.py") {
+ Get-ChildItem -Path ".run/src/bin/*.py" | ForEach-Object {
+ $tools[$_.BaseName] = @{ Type = "py"; Path = $_.FullName }
+ }
+}
+
+if (Test-Path ".run/src/bin/*.rb") {
+ Get-ChildItem -Path ".run/src/bin/*.rb" | ForEach-Object {
+ $tools[$_.BaseName] = @{ Type = "rb"; Path = $_.FullName }
+ }
+}
+
+if (Test-Path ".run/src/bin/*.rs") {
+ Get-ChildItem -Path ".run/src/bin/*.rs" | ForEach-Object {
+ $tools[$_.BaseName] = @{ Type = "rs"; Path = $_.FullName }
+ }
+}
+
+if (Test-Path ".run/src/bin/*.zig") {
+ Get-ChildItem -Path ".run/src/bin/*.zig" | ForEach-Object {
+ $tools[$_.BaseName] = @{ Type = "zig"; Path = $_.FullName }
+ }
+}
+
+if ($args.Count -eq 0) {
+ $sorted = @($tools.Keys | Sort-Object @{Expression={if ($tools[$_].Type -eq 'ps1') {0} else {1}}}, {$_})
+ $total = $sorted.Count
+ $num_w = $total.ToString().Length
+
+ $max_name = ($sorted | ForEach-Object { $_.Length } | Measure-Object -Maximum).Maximum
+
+ $inner_w = 2 + $num_w + 1 + 1 + $max_name + 2 + 10 + 1 + 2
+ if ($inner_w -lt 38) { $inner_w = 38 }
+
+ $title = '.\run.ps1 <NUMBER/NAME> [ARGS...]'
+ $title_len = $title.Length
+ $dash_total = $inner_w - 2 - $title_len
+ $dash_left = [Math]::Floor($dash_total / 2)
+ $dash_right = $dash_total - $dash_left
+
+ Write-Host ("┌" + ("─" * $dash_left) + " " + $title + " " + ("─" * $dash_right) + "┐")
+ Write-Host ("│" + (" " * $inner_w) + "│")
+
+ $i = 1
+ foreach ($name in $sorted) {
+ $type = $tools[$name].Type
+ $lang = switch ($type) {
+ "ps1" { "PowerShell" }
+ "cs" { "C#" }
+ "exe" { "Binary" }
+ "go" { "Go" }
+ "nim" { "Nim" }
+ "pl" { "Perl" }
+ "py" { "Python" }
+ "rb" { "Ruby" }
+ "rs" { "Rust" }
+ "zig" { "Zig" }
+ }
+ $displayName = $name -replace '[_\-]', ' '
+ $entry = " " + $i.ToString().PadRight($num_w) + ") " + $displayName.PadRight($max_name) + " [$lang]"
+ Write-Host ("│" + $entry.PadRight($inner_w) + "│")
+ $i++
+ }
+
+ Write-Host ("│" + (" " * $inner_w) + "│")
+ Write-Host ("└" + ("─" * $inner_w) + "┘")
+ exit 1
+}
+
+$target_name = $args[0]
+
+if ($target_name -match '^\d+$') {
+ $sorted = @($tools.Keys | Sort-Object @{Expression={if ($tools[$_].Type -eq 'ps1') {0} else {1}}}, {$_})
+ $idx = [int]$target_name - 1
+ if ($idx -ge 0 -and $idx -lt $sorted.Count) {
+ $target_name = $sorted[$idx]
+ } else {
+ Write-Host "Error: invalid number '$target_name', valid range is 1-$($sorted.Count)"
+ exit 1
+ }
+}
+
+if (-not $tools.ContainsKey($target_name)) {
+ $normalized = $target_name.ToLower() -replace '[ _\-\.]', ''
+ $found = $null
+ foreach ($key in $tools.Keys) {
+ $keyNormalized = $key.ToLower() -replace '[ _\-\.]', ''
+ if ($normalized -eq $keyNormalized) {
+ $found = $key
+ break
+ }
+ }
+ if ($found) {
+ $target_name = $found
+ } else {
+ Write-Host "Error: target '$target_name' does not exist"
+ exit 1
+ }
+}
+
+$script_args = $args[1..$args.Count]
+$info = $tools[$target_name]
+
+switch ($info.Type) {
+ "ps1" {
+ & $info.Path @script_args
+ }
+ "cs" {
+ $temp_dir = ".run/target/csproj/$target_name"
+ $null = New-Item -ItemType Directory -Path $temp_dir -Force
+
+ $props_content = @'
+<Project>
+ <PropertyGroup>
+ <BaseOutputPath>$(MSBuildThisFileDirectory)../../csharp/bin</BaseOutputPath>
+ <BaseIntermediateOutputPath>$(MSBuildThisFileDirectory)../../csharp/obj</BaseIntermediateOutputPath>
+ </PropertyGroup>
+</Project>
+'@
+ Set-Content -Path "$temp_dir/Directory.Build.props" -Value $props_content
+
+ $csproj_content = @"
+<Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <OutputType>Exe</OutputType>
+ <TargetFramework>net8.0</TargetFramework>
+ <ImplicitUsings>enable</ImplicitUsings>
+ <Nullable>enable</Nullable>
+ </PropertyGroup>
+
+</Project>
+"@
+ Set-Content -Path "$temp_dir/$target_name.csproj" -Value $csproj_content
+ Copy-Item -Path $info.Path -Destination "$temp_dir/Program.cs" -Force
+
+ dotnet run --project "$temp_dir/$target_name.csproj" -- $script_args
+ }
+ "exe" {
+ & $info.Path $script_args
+ }
+ "go" {
+ go run $info.Path $script_args
+ }
+ "nim" {
+ nim r --hints:off $info.Path $script_args
+ }
+ "pl" {
+ perl $info.Path $script_args
+ }
+ "py" {
+ python $info.Path $script_args
+ }
+ "rb" {
+ ruby $info.Path $script_args
+ }
+ "rs" {
+ if (-not (Test-Path ".run/Cargo.toml")) {
+@"
+[package]
+name = "run_rust"
+version = "0.1.0"
+edition = "2024"
+
+[workspace]
+
+[dependencies]
+"@ | Set-Content -Path ".run/Cargo.toml"
+ }
+ cargo build --manifest-path ".run/Cargo.toml" --target-dir ".run/target" --bin $target_name --quiet
+ $binary = ".run/target/debug/$target_name.exe"
+ if (-not (Test-Path $binary)) {
+ $binary = ".run/target/debug/$target_name"
+ }
+ & $binary $script_args
+ }
+ "zig" {
+ zig run $info.Path $script_args
+ }
+}
+
+exit $LASTEXITCODE
diff --git a/run.sh b/run.sh
new file mode 100644
index 0000000..cc03790
--- /dev/null
+++ b/run.sh
@@ -0,0 +1,257 @@
+#!/bin/bash
+
+#
+# ██ ██████ ██ ██ ███ ██ ███████ ██ ██
+# ██ ██ ██ ██ ██ ████ ██ ██ ██ ██
+# ██ ██████ ██ ██ ██ ██ ██ ███████ ███████
+# ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
+# ██ ██ ██ ██ ██████ ██ ████ ██ ███████ ██ ██
+#
+# You can go to [https://catilgrass.github.io/run] to install it
+# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+cd "$(dirname "$0")" || exit 1
+
+declare -A tools
+
+for file in .run/src/bin/*.sh; do
+ if [ -f "$file" ]; then
+ name=$(basename "$file" .sh)
+ tools["$name"]="sh"
+ fi
+done
+
+for file in .run/src/bin/*; do
+ if [ -f "$file" ]; then
+ name=$(basename "$file")
+ if [[ ! "$name" == *.* ]]; then
+ tools["$name"]="binary"
+ fi
+ fi
+done
+
+for file in .run/src/bin/*.cs; do
+ if [ -f "$file" ]; then
+ name=$(basename "$file" .cs)
+ tools["$name"]="cs"
+ fi
+done
+
+for file in .run/src/bin/*.go; do
+ if [ -f "$file" ]; then
+ name=$(basename "$file" .go)
+ tools["$name"]="go"
+ fi
+done
+
+for file in .run/src/bin/*.nim; do
+ if [ -f "$file" ]; then
+ name=$(basename "$file" .nim)
+ tools["$name"]="nim"
+ fi
+done
+
+for file in .run/src/bin/*.pl; do
+ if [ -f "$file" ]; then
+ name=$(basename "$file" .pl)
+ tools["$name"]="pl"
+ fi
+done
+
+for file in .run/src/bin/*.py; do
+ if [ -f "$file" ]; then
+ name=$(basename "$file" .py)
+ tools["$name"]="py"
+ fi
+done
+
+for file in .run/src/bin/*.rb; do
+ if [ -f "$file" ]; then
+ name=$(basename "$file" .rb)
+ tools["$name"]="rb"
+ fi
+done
+
+for file in .run/src/bin/*.rs; do
+ if [ -f "$file" ]; then
+ name=$(basename "$file" .rs)
+ tools["$name"]="rs"
+ fi
+done
+
+for file in .run/src/bin/*.zig; do
+ if [ -f "$file" ]; then
+ name=$(basename "$file" .zig)
+ tools["$name"]="zig"
+ fi
+done
+
+if [ $# -eq 0 ]; then
+ sorted_names=($(
+ for name in "${!tools[@]}"; do
+ if [ "${tools[$name]}" = "sh" ]; then
+ echo "0 $name"
+ else
+ echo "1 $name"
+ fi
+ done | sort | while read -r _ n; do echo "$n"; done
+ ))
+ total=${#sorted_names[@]}
+ num_w=${#total}
+
+ max_name=0
+ for name in "${sorted_names[@]}"; do
+ len=${#name}
+ ((len > max_name)) && max_name=$len
+ done
+
+ inner_w=$((2 + num_w + 1 + 1 + max_name + 2 + 6 + 1 + 2))
+ ((inner_w < 38)) && inner_w=38
+
+ title="./run.sh <NUMBER/NAME> [ARGS...]"
+ title_len=${#title}
+ dash_total=$((inner_w - 2 - title_len))
+ dash_left=$((dash_total / 2))
+ dash_right=$((dash_total - dash_left))
+
+ echo "┌$(printf '─%.0s' $(seq 1 $dash_left)) $title $(printf '─%.0s' $(seq 1 $dash_right))┐"
+ printf "│%*s│\n" $inner_w ""
+
+ i=1
+ for name in "${sorted_names[@]}"; do
+ type="${tools[$name]}"
+ case "$type" in
+ sh) lang="Shell";;
+ binary) lang="Binary";;
+ cs) lang="C#";;
+ go) lang="Go";;
+ nim) lang="Nim";;
+ pl) lang="Perl";;
+ py) lang="Python";;
+ rb) lang="Ruby";;
+ rs) lang="Rust";;
+ zig) lang="Zig";;
+ esac
+ display_name=$(echo "$name" | tr '_-' ' ')
+ entry=$(printf " %-*d) %-*s [%s]" $num_w $i $max_name "$display_name" $lang)
+ printf "│%-*s│\n" $inner_w "$entry"
+ i=$((i + 1))
+ done
+
+ printf "│%*s│\n" $inner_w ""
+ echo "└$(printf '─%.0s' $(seq 1 $inner_w))┘"
+ exit 1
+fi
+
+target_name="$1"
+shift
+
+if [[ "$target_name" =~ ^[0-9]+$ ]]; then
+ sorted=($(
+ for name in "${!tools[@]}"; do
+ if [ "${tools[$name]}" = "sh" ]; then
+ echo "0 $name"
+ else
+ echo "1 $name"
+ fi
+ done | sort | while read -r _ n; do echo "$n"; done
+ ))
+ idx=$((target_name - 1))
+ if [ "$idx" -ge 0 ] && [ "$idx" -lt "${#sorted[@]}" ]; then
+ target_name="${sorted[$idx]}"
+ else
+ echo "Error: invalid number '$target_name', valid range is 1-${#sorted[@]}"
+ exit 1
+ fi
+fi
+
+if [ -z "${tools[$target_name]}" ]; then
+ normalized_user=$(echo "$target_name" | tr '[:upper:]' '[:lower:]' | sed 's/[_. -]//g')
+ found=""
+ for existing_name in "${!tools[@]}"; do
+ normalized_existing=$(echo "$existing_name" | tr '[:upper:]' '[:lower:]' | sed 's/[_. -]//g')
+ if [ "$normalized_user" = "$normalized_existing" ]; then
+ found="$existing_name"
+ break
+ fi
+ done
+ if [ -n "$found" ]; then
+ target_name="$found"
+ else
+ echo "Error: target '$target_name' does not exist"
+ exit 1
+ fi
+fi
+
+type="${tools[$target_name]}"
+
+case "$type" in
+ sh)
+ chmod +x ".run/src/bin/$target_name.sh"
+ ".run/src/bin/$target_name.sh" "$@"
+ ;;
+ binary)
+ chmod +x ".run/src/bin/$target_name"
+ ".run/src/bin/$target_name" "$@"
+ ;;
+ cs)
+ temp_dir=".run/target/csproj/$target_name"
+ mkdir -p "$temp_dir"
+ cat > "$temp_dir/Directory.Build.props" <<'PROPS'
+<Project>
+ <PropertyGroup>
+ <BaseOutputPath>$(MSBuildThisFileDirectory)../../csharp/bin</BaseOutputPath>
+ <BaseIntermediateOutputPath>$(MSBuildThisFileDirectory)../../csharp/obj</BaseIntermediateOutputPath>
+ </PropertyGroup>
+</Project>
+PROPS
+ cat > "$temp_dir/$target_name.csproj" <<'CSPROJ'
+<Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <OutputType>Exe</OutputType>
+ <TargetFramework>net8.0</TargetFramework>
+ <ImplicitUsings>enable</ImplicitUsings>
+ <Nullable>enable</Nullable>
+ </PropertyGroup>
+
+</Project>
+CSPROJ
+ cp ".run/src/bin/$target_name.cs" "$temp_dir/Program.cs"
+ dotnet run --project "$temp_dir/$target_name.csproj" -- "$@"
+ ;;
+ go)
+ go run ".run/src/bin/$target_name.go" "$@"
+ ;;
+ nim)
+ nim r --hints:off ".run/src/bin/$target_name.nim" "$@"
+ ;;
+ pl)
+ perl ".run/src/bin/$target_name.pl" "$@"
+ ;;
+ py)
+ python ".run/src/bin/$target_name.py" "$@"
+ ;;
+ rb)
+ ruby ".run/src/bin/$target_name.rb" "$@"
+ ;;
+ rs)
+ if [ ! -f ".run/Cargo.toml" ]; then
+ cat > ".run/Cargo.toml" <<'EOF'
+[package]
+name = "run_rust"
+version = "0.1.0"
+edition = "2024"
+
+[workspace]
+
+[dependencies]
+EOF
+ fi
+ cargo build --manifest-path ".run/Cargo.toml" --target-dir ".run/target" --bin "$target_name" --quiet
+ ".run/target/debug/$target_name" "$@"
+ ;;
+ zig)
+ zig run ".run/src/bin/$target_name.zig" "$@"
+ ;;
+esac