diff options
| author | 魏曹先生 <1992414357@qq.com> | 2026-05-31 17:08:39 +0800 |
|---|---|---|
| committer | 魏曹先生 <1992414357@qq.com> | 2026-05-31 17:08:39 +0800 |
| commit | 2e0ed19550f76b1df0658c5b745f85f36f238d37 (patch) | |
| tree | 638cd07a07412b4a67ca0e312508e39e1745e396 | |
| parent | 727ba2473beb98f071196a15ce74a811ba4f4c72 (diff) | |
Add unpack_chain_process macro and improve test docs
| -rw-r--r-- | CHANGELOG.md | 37 | ||||
| -rw-r--r-- | mingling_core/src/tester/chain_process_tester.rs | 143 |
2 files changed, 172 insertions, 8 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 6c54bc4..5ec5cce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,14 +1,39 @@ # Changelogs +### Release 0.2.0 (Unreleased) + +#### Fixes: + +None + +#### Optimizations: + +None + +#### Features: + +1. **\[core\]** Added the `unpack_chain_process!` macro for ergonomically extracting the inner value from a `ChainProcess` result. + +This macro wraps `::mingling::test::unpack_chain_process_result` to downcast a `ChainProcess::Ok` result to the specified type. It panics if the result is `ChainProcess::Err` or if the downcast fails. + +```rust +let result = some_chain_function(args).into(); +let value: MyType = unpack_chain_process!(result, MyType); +``` + +#### **BREAKING CHANGES** (API CHANGES): + +None + ### Release 0.1.9 (2026-05-29) -### Fixes: +#### 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 -### Optimizings: +#### Optimizations: 1. **\[macros\]** Removed dependency `once_cell`, replaced with `std::sync::OnceLock` @@ -90,9 +115,9 @@ dispatcher!("remote.remove", CMDRemoteRemove => EntryRemoteRemove); 8. **\[macros\]** The `pack!` macro now supports adding doc comments and attributes (e.g., `#[doc(hidden)]`) to the inner structs: ```rust -pack!{ +pack!{ /// Your comment - StateGreet = String + StateGreet = String } pack! { @@ -172,7 +197,7 @@ gen_program!(); None -#### Optimizings: +#### Optimizations: 1. **\[core\]** The core library no longer depends on `thiserror` @@ -334,7 +359,7 @@ fn your_chain(_prev: Prev) -> Next { 1. Fixed a build failure on **Windows** caused by `mingling_core/src/program.rs` 2. **\[picker\]** Fixed an issue where the `Pickable` trait for `Yes` and `True` types could not correctly parse explicit boolean `--value true` -#### Optimizings: +#### Optimizations: 1. **\[macros\]** Optimized the memory usage of the `gen_program!()` macro: the internal generated enum now uses the smallest possible integer representation (`u8`, `u16`, `u32`, or `u128`) based on the number of packed types, instead of always using `u32`. diff --git a/mingling_core/src/tester/chain_process_tester.rs b/mingling_core/src/tester/chain_process_tester.rs index 20277fb..8189c28 100644 --- a/mingling_core/src/tester/chain_process_tester.rs +++ b/mingling_core/src/tester/chain_process_tester.rs @@ -52,7 +52,76 @@ where } } +/// Unpacks the inner value from a `ChainProcess::Ok` result by downcasting it to the expected type. +/// +/// This function extracts a reference to the output value of type `Type` from a `ChainProcess` +/// result. It is useful when you know the exact output type and just want to get a reference to +/// the inner data, without having to match on the enum yourself. +/// +/// # Parameters +/// +/// * `result` - A reference to the chain process result to unpack. +/// +/// # Generic Constraints +/// +/// * `C` - Must implement `ProgramCollect`, `Display`, `PartialEq` and have a `'static` lifetime. +/// * `Type` - The expected output type. Must be `'static` and match the actual output type stored +/// in the result. +/// +/// # Panics +/// +/// Panics in the following cases: +/// - The result is `ChainProcess::Err`, outputting the error message via `Debug`. +/// - The downcast fails because the actual output type does not match `Type`, panicking with a +/// message indicating a type mismatch. +/// +/// # Returns +/// +/// A reference to the inner value of type `Type` if the result is `ChainProcess::Ok` and the +/// downcast succeeds. +pub fn unpack_chain_process_result<C, Type: 'static>(result: &ChainProcess<C>) -> &Type +where + C: ProgramCollect + Display + PartialEq + 'static, +{ + match result { + ChainProcess::Ok((any, _next)) => any + .downcast_ref::<Type>() + .expect("Type mismatch: expected type does not match actual output type"), + ChainProcess::Err(chain_process_error) => panic!("{:?}", chain_process_error), + } +} + /// Asserts that a chain process result has the expected output type and next state. +/// +/// This macro provides a convenient way to verify that a `ChainProcess` result meets expectations. +/// It wraps `assert_next_eq`, allowing optional checks on the output type (`member_id`) and the +/// next processing state. +/// +/// # Parameters +/// +/// * `$result` - An expression evaluating to a `ChainProcess<C>`. +/// * `$expected_next` - (Optional) The expected next state, expressed as a path. If provided, the +/// macro checks that the result's next state matches this value. +/// * `$expected_type` - (Optional) The expected output type, expressed as a path. If provided, the +/// macro checks that the result's `member_id` matches this value. +/// +/// # Panics +/// +/// Panics if the result is `ChainProcess::Err`, or if any provided expectation does not match the +/// actual value. +/// +/// # Examples +/// +/// ```ignore +/// // Check both next state and output type +/// assert_next!(result, NextProcess::End, MyOutputType); +/// +/// // Check only next state +/// assert_next!(result, NextProcess::End); +/// +/// // Check only that the result is Ok +/// assert_next!(result); +/// ``` #[macro_export] macro_rules! assert_next { ($result:expr, $expected_next:path, $expected_type:path) => { @@ -66,7 +135,26 @@ macro_rules! assert_next { }; } -/// Asserts that a chain process result is Ok and has the expected output type. +/// Asserts that a chain process result is `Ok` without checking the output type or next state. +/// +/// This macro checks that the `ChainProcess` result is `ChainProcess::Ok`, panicking if it is +/// `ChainProcess::Err`. It does **not** validate the output type identifier (`member_id`) or the +/// next processing state, making it useful when you only need to verify that the chain completed +/// without errors. +/// +/// # Parameters +/// +/// * `$result` - An expression evaluating to a `ChainProcess<C>`. +/// +/// # Panics +/// +/// Panics if the result is `ChainProcess::Err`, displaying the error message. +/// +/// # Example +/// +/// ```ignore +/// assert_chain_result!(result); +/// ``` #[macro_export] macro_rules! assert_chain_result { ($result:expr) => { @@ -74,7 +162,24 @@ macro_rules! assert_chain_result { }; } -/// Alias for assert_chain_result. +/// Alias for `assert_chain_result`. +/// +/// This macro provides a more semantic name when asserting the result of a render operation. +/// It checks that the `ChainProcess` result is `Ok` without verifying specific output types or next states. +/// +/// # Parameters +/// +/// * `$result` - An expression evaluating to a `ChainProcess<C>`. +/// +/// # Panics +/// +/// Panics if the result is `ChainProcess::Err`, displaying the error message. +/// +/// # Example +/// +/// ```ignore +/// assert_render_result!(result); +/// ``` #[macro_export] macro_rules! assert_render_result { ($result:expr) => { @@ -83,9 +188,43 @@ macro_rules! assert_render_result { } /// Asserts that the result's output type matches the expected member_id. +/// +/// This macro checks that the `ChainProcess` result is `Ok` and that its output type identifier +/// matches the expected type. It is a convenience wrapper around `assert_next_eq` with the `next` +/// check skipped. +/// +/// # Parameters +/// +/// * `$result` - An expression evaluating to a `ChainProcess<C>`. +/// * `$expected_type` - The expected output type (a path like `SomeType`). +/// +/// # Panics +/// +/// Panics if the result is `ChainProcess::Err` or if the output `member_id` does not match the +/// expected type. #[macro_export] macro_rules! assert_member_id { ($result:expr, $expected_type:path) => { ::mingling::test::assert_next_eq(&$result, None, Some($expected_type)) }; } + +/// Unpacks a `ChainProcess::Ok` result by downcasting to the specified type. +/// +/// This macro wraps the function `::mingling::test::unpack_chain_process_result` to provide +/// a more ergonomic way to extract the inner value from a chain process result. +/// +/// # Parameters +/// +/// * `$result` - A reference to or expression evaluating to a `ChainProcess<C>`. +/// * `$type` - The expected output type to downcast to. +/// +/// # Panics +/// +/// Panics if the result is `ChainProcess::Err` or if the downcast fails. +#[macro_export] +macro_rules! unpack_chain_process { + ($result:expr, $type:ty) => { + ::mingling::test::unpack_chain_process_result::<_, $type>(&$result) + }; +} |
