aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md37
-rw-r--r--mingling_core/src/tester/chain_process_tester.rs143
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)
+ };
+}