diff options
Diffstat (limited to 'CHANGELOG.md')
| -rw-r--r-- | CHANGELOG.md | 96 |
1 files changed, 94 insertions, 2 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index b483cfe..2d9198b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,7 @@ Any contributor making changes to the project must record their changes in this **- Milestone.1 "MVP" -** - [Unreleased](#unreleased) -- [Release 0.3.0 (Unreleased)](#release-030-unreleased) +- [Release 0.3.0 (2026-07-27)](#release-030-2026-07-27) - [Release 0.2.2 (2026-07-10)](#release-022-2026-07-10) - [Release 0.2.1 (2026-07-01)](#release-021-2026-07-01) - [Release 0.2.0 (2026-06-30)](#release-020-2026-06-30) @@ -50,7 +50,99 @@ None --- -### Release 0.3.0 (Unreleased) +## Contents + +### ?.?.? (Unreleased) + +#### Fixes: + +None + +#### Optimizations: + +1. **[`pathf`]** Added `is_module` field to `AnalyzeItem` and a new constructor `AnalyzeItem::local_module(module, item_name)` which sets `is_module: true`. The `type_mapping_builder` now tracks whether an item is a module: when generating `type_using.rs`, module items produce `use path::to::module::*;` (glob import) instead of the standard `use path::to::TypeName;` direct import. Non-module items continue to use direct imports as before. The internal data structure changed from `Vec<(String, String)>` to `Vec<(String, String, bool)>` to carry the `is_module` flag through the pipeline. + +2. **[`macros:gen_program`]** Wrapped all code generated by `gen_program!()` inside a `__this_program_impl` module and re-exported it with `pub use __this_program_impl::*;`. This isolates the generated internal items (type aliases, trait implementations, and pathf-generated `use` statements) from the call site's module namespace, preventing name collisions and keeping generated machinery out of the caller's direct scope. + + - The `Next` type alias, `Routable` impl for `ChainProcess<ThisProgram>`, and the `program_fallback_gen!()` / `program_final_gen!()` expansions are now all inside `pub mod __this_program_impl { ... }`, then re-exported publicly. + - Pathf integration: when the `pathf` feature is enabled, the `type_using.rs` file (generated by the build script) is loaded at compile time via `load_pathf_uses()` and emitted as `use ...;` statements **inside** the `__this_program_impl` module. Previously, pathf uses were injected via `include!()` inside the `ProgramCollect` impl block in `program_final_gen`; now they are loaded by `gen_program` itself and placed at the top of the hidden module. A `compile_error!` hint is emitted if the pathf file is missing or empty. + - When `pathf` is **disabled**, `__this_program_impl` emits `use super::*;` to bring the caller's parent scope types into the generated module, preserving existing behavior for projects that don't use pathf. + - Completion generation: removed `crate::` prefix from `CompletionSuggest` references in `program_comp_gen.rs`, since the generated code now lives inside `__this_program_impl` and no longer has a direct `crate` path to the user's crate root. The prefix became unnecessary because `CompletionSuggest` is expected to be in scope (e.g., via pathf glob re-exports or the `use super::*;` fallback). + + _No behavioral change for downstream code — all public items are re-exported with the same names. The `__this_program_impl` module is `#[doc(hidden)]` and not part of the public API._ + +#### Features: + +1. **[`picker:value:paths`]** Added new path wrapper types to `arg_picker::value` for filesystem-aware argument parsing: + + - **`FilePath`** — Wraps `PathBuf`, validated at parse time to exist and be a file. + - **`NoFilePath`** — Wraps `PathBuf`, validated at parse time to _not_ exist as a file. + - **`DirPath`** — Wraps `PathBuf`, validated at parse time to exist and be a directory. + - **`NoDirPath`** — Wraps `PathBuf`, validated at parse time to _not_ exist as a directory. + - **`SymlinkPath`** — Wraps `PathBuf`, validated at parse time to exist and be a symlink. + - **`NoSymlinkPath`** — Wraps `PathBuf`, validated at parse time to _not_ exist as a symlink. + - **`NoPath`** — Wraps `PathBuf`, validated at parse time to have no filesystem entry at all. + - **`RecursiveFiles`** — Wraps `Vec<PathBuf>`. If given a file path, returns a single-element list; if given a directory path, recursively collects all files (and symlinks) under it. + + All single-path types implement `From<PathBuf>`, `From<&PathBuf>`, `AsRef<Path>`, `Deref<Target = PathBuf>`, `DerefMut`, and `Into<PathBuf>`. `RecursiveFiles` additionally provides `len()`, `is_empty()`, `iter()`, `From<Vec<RecursiveFiles>>` for merging multiple collections, and the `IntoRecursiveFiles` trait for ergonomic combination from `Vec<T>`, `&[T]`, and `[T; N]`. + + Each type implements `SinglePickable`, performing filesystem validation at parse time and returning `NotFound` when the precondition is not met. + +2. **[`picker:parsing`]** Added convenience methods to the internal `repeat!`-generated tuple implementations for `PickArgParsed<T1, T2, ...>` structs in `arg_picker::picker::parse`: + + - **`unwrap_or_default(self)`** — Returns the parsed values, using `Default::default()` for any missing required arguments. Panics if a route was selected. + - **`unwrap_or_else<F>(self, op: F)`** — Returns the parsed values, using the provided closure to generate default values for any missing required arguments. Panics if a route was selected. + - **`expect(self, msg: &str)`** — Returns the parsed values, or panics with the given message if a route was selected. Requires `Route: std::fmt::Debug`. + + These methods provide ergonomic alternatives to `to_result()` + `unwrap()` / `unwrap_or_default()` / `unwrap_or_else()` / `expect()` chaining, reducing boilerplate when working with `PickArgParsed` tuples directly. + +3. **[`macros:command`]** Added the `#[command]` attribute macro (feature-gated behind `extra_macros`) that converts a plain function with a `Vec<String>` parameter into a fully wired Mingling command. The macro: + + - Calls `dispatcher!("command_name")` to register the dispatcher entry. + - Generates a `#[chain]` wrapper that bridges the entry type (`Entry{Pascal}`) to the original function. + - Preserves the original function unchanged (including attributes, extensions, visibility, and asyncness). + + **Syntax variants:** + + ```rust,ignore + // Simple form — auto-derives names from function name + #[command] + fn greet(args: Vec<String>) -> Next { /* ... */ } + // → dispatcher!("greet"), CMDGreet, EntryGreet + + // Explicit node path + #[command(node = "hello.world")] + fn greet(args: Vec<String>) -> Next { /* ... */ } + // → dispatcher!("hello.world", CMDGreet => EntryGreet) + + // Explicit name/entry overrides + #[command(name = MyDispatcher, entry = MyEntry)] + fn greet(args: Vec<String>) -> Next { /* ... */ } + // → dispatcher!("greet", MyDispatcher => MyEntry) + ``` + + **Extension attributes** (e.g. `buffer`, `routeify`) passed as bare paths in `#[command(...)]` are applied as `#[ext]` attributes **on the original function**, not on the generated chain wrapper. The chain wrapper always uses bare `#[::mingling::macros::chain]`. + + **Resource injection:** Parameters after the first are treated as resource injections and passed through to the generated `#[chain]` wrapper unchanged. + + **Hidden module:** Each `#[command]` generates a `#[doc(hidden)]` module `__command_{fn_name}_module` that re-exports all generated types (`CMD*`, `Entry*`, chain struct, dispatcher static) for pathf / external access. + + Internally, the implementation: + - Parses `#[command(...)]` arguments via `CommandArgs` supporting `node`, `name`, `entry` keys and extension paths. + - Validates function constraints (no `self`, at least one parameter). + - Handles async functions (rejected without the `async` feature). + - Resolves default names via `just_fmt::dot_case!` / `just_fmt::pascal_case!`. + - Builds a chain wrapper that calls the original function with `entry.into()` for the first argument. + +4. **[`pathf:patterns`]** Added `CommandPattern` to the `pathf` pattern analyzer, matching functions annotated with `#[command]`. The pattern tracks the generated hidden module (`__command_{fn}_module`) and marks it as a local module item via `AnalyzeItem::local_module()`. The build system generates a glob re-export `use path::__command_{fn}_module::*;` to bring all generated types (`Entry*`, `CMD*`, chain struct, dispatcher static) into scope. + +#### **BREAKING CHANGES** (API CHANGES): + +None + +--- + +### Release 0.3.0 (2026-07-27) > In detail, the changes in Mingling 0.3.0 are as follows: |
