diff options
Diffstat (limited to 'CHANGELOG.md')
| -rw-r--r-- | CHANGELOG.md | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index ed7ad66..da1c26a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -171,6 +171,33 @@ None _No migration is required — these are purely additive derives that expand the type's capabilities without affecting existing behavior._ +**[`core`]** Added the `build` feature (renamed from `builds`) to `mingling_core` and `mingling`. The old `builds` feature has been deprecated in favor of `build`, with a backward-compatibility alias retained in `mingling/Cargo.toml`: + +- **`mingling_core/Cargo.toml`**: Renamed the feature from `builds` to `build`. +- **`mingling/Cargo.toml`**: Changed the feature dependency from `mingling_core/builds` to `mingling_core/build`. A deprecated `builds` feature alias is kept as `builds = ["mingling_core/build"]` with a note indicating it will be removed in a future breaking change. + + _No behavioral changes — the `build` feature provides identical functionality to the old `builds` feature. Downstream code using `builds` continues to work via the alias, but should migrate to `build`._ + +8. **[`core`]** Renamed `ResourceMarker` methods from public names (`res_clone`, `res_default`, `modify`) to doc-hidden internal names (`__resource_marker_clone`, `__resource_marker_default`, `__resource_marker_modify`). These methods are internal implementation details of the resource injection system and should not be called directly by user code. By prefixing with `__` and adding `#[doc(hidden)]`, they are still technically accessible but hidden from documentation and tooling, reducing API surface confusion. + + - **`res_clone()`** → **`__resource_marker_clone()`** — Internal method for cloning a resource value during resource injection. + - **`res_default()`** → **`__resource_marker_default()`** — Internal method for creating a default resource value during resource injection. + - **`modify<C>()`** → **`__resource_marker_modify<C>()`** — Internal method for in-place modification of a resource during resource injection. + + All internal usages within `global_resource.rs` and `lazy_resource.rs` have been updated to use the renamed methods. Test code has been updated accordingly. + + A new module `mingling_core::asset::core_invokes` has been added to provide a centralized location for internal invocation helpers. + +9. **[`core:exec`]** Refactored the program execution pipeline (`exec` and `exec_with_args`) to use the `might_be_async` crate instead of manual `#[cfg(feature = "async")]` duplication. The previously separate sync and async implementations have been consolidated into a single `#[might_be_async::func]`-annotated function, with `might_be_async::invoke!()` wrapping the `C::do_chain(current)` call inside `exec_with_args` and the delegation from `exec` to `exec_with_args`. + + The `exec` function no longer contains the full execution loop inline. Instead, it delegates to `exec_with_args` (which now also carries the `#[might_be_async::func]` annotation), reducing code duplication and centralizing the execution logic. + + - **`exec`**: Changed from separate `#[cfg(feature = "async")]` and `#[cfg(not(feature = "async"))]` implementations to a single `#[might_be_async::func]` function that calls `might_be_async::invoke!(exec_with_args(program, &program.args))`. + - **`exec_with_args`**: Changed from separate implementations to a single `#[might_be_async::func]` function. The `C::do_chain(current)` call is now wrapped with `might_be_async::invoke!(C::do_chain(current))` to support both sync and async chain execution. + - **Removed**: The `error.rs` submodule import remains, but the separate sync/async code blocks in the function bodies have been eliminated. + + _No behavioral changes. All existing functionality — hooks, help handling, chain execution, renderer dispatch, and exit code management — is preserved identically._ + #### Features: 1. **[`core`]** Added `RenderResult::new()` method for creating a new `RenderResult` with default values (empty text and exit code 0). This provides a more explicit and discoverable constructor compared to `RenderResult::default()`, making it clearer when a fresh result is being created for use with `write!`/`writeln!`. @@ -434,6 +461,56 @@ None Since the attribute is a no-op at compile time, it has no effect on code generation, type checking, or runtime behavior. Its purpose is to serve as a structured annotation that `mlint` tooling can parse from the AST. The attribute is feature-gated behind `extra_macros`. +16. **[`core`]** Added `RendererInvoker<T, C>` and `ChainInvoker<T, C>` types to `mingling_core::asset::core_invokes`, providing a mechanism for selectively invoking renderer and chain pipelines for specific types from within chain/renderer functions via resource injection. + + These types are designed to be created **only** through the resource injection system (via `ResourceMarker::__resource_marker_default`), and attempting to invoke them without being properly injected will panic. They are marked `#[non_exhaustive]` with private fields, so they cannot be constructed by user code. + + ### `RendererInvoker<T, C>` + + Allows invoking the renderer pipeline for a specific type `T`. Use cases include: + - **Reusing** — calling another renderer's output from within a `#[renderer]` or `#[chain]` function + - **Bypassing** — directly rendering intermediate values without going through the chain pipeline + + ```rust,ignore + #[renderer(buffer)] + fn render_foo(_: ResultFoo, renderer: &RendererInvoker<Bar>) { + let bar = Bar::default(); + r_append!(renderer.invoke(bar)); + } + ``` + + **Methods:** + - `invoke(&self, value: T) -> RenderResult` — Invokes the renderer for value `T`, returning the rendered output. Does **not** execute program hooks (by design — this is for bypassing/reusing, not flow control). + + ### `ChainInvoker<T, C>` + + Allows executing chain steps for a specific type `T`. Use cases include: + - **Sub-routing** — dispatching to a sub-chain from within a chain handler + - **Re-entering** — re-processing a value through the chain pipeline + + ```rust,ignore + #[chain] + fn handle_foo(_: EntryFoo, chain: &ChainInvoker<StateBar>) -> Next { + let bar = Bar::default(); + // Execute one step of the chain + let next = chain.invoke_once(bar); + // ... handle the result + next + } + ``` + + **Methods:** + - `invoke_once(&self, value: T) -> ChainProcess<C>` — Executes a **single step** of chain processing for value `T`. If no chain exists for the type, it converts the value into a `ChainProcess::Ok` with `NextProcess::Chain` routing. Does **not** execute program hooks. + - `invoke_to_last(&self, value: T) -> ChainProcess<C>` — Continuously executes the chain for value `T` until it is routed to a renderer or can no longer continue. Each step calls `C::do_chain(any)`. If a step produces a `ChainProcess::Ok` with `NextProcess::Chain` and the next type has no chain handler, it stops and returns that state. Non-chain results (e.g., `ChainProcess::Err`) are returned immediately. + - `invoke_to_result(&self, value: T) -> RenderResult` — Convenience method that runs the chain to completion via `invoke_to_last` and then renders the final result. If the final result lacks a renderer or is an error, returns an empty `RenderResult`. + + Both types implement `ResourceMarker` (via `__resource_marker_clone`, `__resource_marker_default`, and `__resource_marker_modify`) which: + - `__resource_marker_default` creates instances with `create_by_res_injection: true`, allowing invocation. + - `__resource_marker_clone` preserves the `create_by_res_injection` flag. + - `__resource_marker_modify` is a no-op (these invokers are not meant to be modified at runtime). + + The types are re-exported from `mingling_core` and exposed to the `mingling` crate root. + #### **BREAKING CHANGES** (API CHANGES): 1. **[`macros:renderer`]** **[`macros:help`]** Removed `r_println!` and `r_print!` macros from being implicitly injected by `#[renderer]` and `#[help]` macros. These macros still exist, but must now be used **explicitly** — either with an explicit buffer argument, or via the `#[buffer]` extension attribute that re-enables implicit buffer injection. |
