diff options
| author | 魏曹先生 <1992414357@qq.com> | 2026-06-27 17:46:29 +0800 |
|---|---|---|
| committer | 魏曹先生 <1992414357@qq.com> | 2026-06-27 17:46:29 +0800 |
| commit | 4f7bd4f6fa5d27cfe703c54aa029a321f40d19fb (patch) | |
| tree | 97c31ddbb905d8f0e70418b0970ee6420aeac611 /CHANGELOG.md | |
| parent | 6cadc8d39adebbc263e8576c389b5ef491f10ace (diff) | |
feat(macros): add async mutable resource injection for `#[chain]`
Support `&mut T` resource parameters in async chain functions by using
an extract-store pattern that avoids holding mutable borrows across
await
points. Remove the previous compile-time rejection of this combination.
Diffstat (limited to 'CHANGELOG.md')
| -rw-r--r-- | CHANGELOG.md | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 60b8f2c..7cc4e6f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -243,6 +243,22 @@ fn comp_my_entry(ctx: &ShellContext, res: &mut ResA) -> Suggest { For mutable resources (`&mut T`), both macros use `Program::modify_res` (with constraint `Return: Default`) instead of `#[chain]`'s dedicated `__modify_res_and_return_route` (with constraint `Return: Into<ChainProcess>`), because the return types of help/completion are `()` and `Suggest` respectively. +12. **\[macros\]** Added async mutable resource injection support for `#[chain]`. Previously, async chain functions could only use `&T` (immutable) resource injection; `&mut T` was rejected with a compile-time error. Now, async chain functions support `&mut T` resource injection by using an extract‑store pattern: each mutable resource is cloned out of the global store before the body executes (via `__extract_res_mut`), bound as `&mut` within a scoped block, and written back after the block completes (via `__store_res`). This avoids holding a mutable borrow across `.await` points while still providing a natural `&mut T` syntax. + +```rust +use mingling::macros::{chain, pack, gen_program}; + +pack!(MyOutput = String); + +#[chain] +async fn greet(prev: HelloEntry, ec: &mut ResExitCode) -> Next { + let name = prev.first().cloned().unwrap_or_else(|| "World".to_string()); + ec.exit_code = 42; + some_async_fn(&name).await; + MyOutput::new(name) +} +``` + #### **BREAKING CHANGES** (API CHANGES): --- |
