MCPcopy Create free account
hub / github.com/carllerche/assert-struct / expand_set_assertion

Function expand_set_assertion

assert-struct-macros/src/expand.rs:754–800  ·  view source on GitHub ↗

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)

Source from the content-addressed store, hash-verified

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.
754fn 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(&quote! { __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
803fn generate_error_push(

Callers 1

expand_pattern_assertionFunction · 0.85

Calls 3

expand_pattern_assertionFunction · 0.85
lenMethod · 0.80

Tested by

no test coverage detected