Generate set assertion using backtracking to match patterns in any order. Each element pattern becomes a predicate closure that shadows `__report` with a probe report, allowing the existing assertion code to be reused unchanged. The runtime `set_match` function owns the length check and backtracking algorithm.
(value_expr: &TokenStream, pattern: &PatternSet)
| 752 | /// probe report, allowing the existing assertion code to be reused unchanged. The |
| 753 | /// runtime `set_match` function owns the length check and backtracking algorithm. |
| 754 | fn expand_set_assertion(value_expr: &TokenStream, pattern: &PatternSet) -> TokenStream { |
| 755 | let elements = &pattern.elements; |
| 756 | let rest = pattern.rest; |
| 757 | let node_ident = expand_pattern_node_ident(pattern.node_id); |
| 758 | |
| 759 | // Generate one named predicate binding per element pattern. |
| 760 | // Each closure: |
| 761 | // 1. Looks up the element by index from __set_coll (captured by ref) |
| 762 | // 2. Shadows __report with a fresh probe report |
| 763 | // 3. Runs the generated assertion (which writes to the local __report) |
| 764 | // 4. Returns true iff no errors were pushed (i.e. the pattern matched) |
| 765 | let pred_names: Vec<_> = (0..elements.len()) |
| 766 | .map(|i| quote::format_ident!("__set_pred_{}", i)) |
| 767 | .collect(); |
| 768 | |
| 769 | let pred_defs: Vec<TokenStream> = elements |
| 770 | .iter() |
| 771 | .zip(pred_names.iter()) |
| 772 | .map(|(elem, name)| { |
| 773 | let assertion = expand_pattern_assertion("e! { __set_elem }, elem); |
| 774 | quote! { |
| 775 | let #name = |__set_idx: usize| -> bool { |
| 776 | let __set_elem = __set_coll[__set_idx]; |
| 777 | #[allow(unused_mut)] |
| 778 | let mut __report = ::assert_struct::__macro_support::ErrorReport::new_probe(); |
| 779 | #assertion |
| 780 | __report.is_empty() |
| 781 | }; |
| 782 | } |
| 783 | }) |
| 784 | .collect(); |
| 785 | |
| 786 | quote! { |
| 787 | { |
| 788 | let __set_coll: ::std::vec::Vec<_> = (&(#value_expr)).into_iter().collect(); |
| 789 | #(#pred_defs)* |
| 790 | let __set_preds: &[&dyn ::std::ops::Fn(usize) -> bool] = &[#(&#pred_names),*]; |
| 791 | ::assert_struct::__macro_support::set_match( |
| 792 | __set_coll.len(), |
| 793 | #rest, |
| 794 | __set_preds, |
| 795 | &mut __report, |
| 796 | &#node_ident, |
| 797 | ); |
| 798 | } |
| 799 | } |
| 800 | } |
| 801 | |
| 802 | /// Generate the error context creation and push code |
| 803 | fn generate_error_push( |
no test coverage detected