Generate slice assertion with error collection
(value_expr: &TokenStream, pattern: &PatternSlice)
| 548 | |
| 549 | /// Generate slice assertion with error collection |
| 550 | fn expand_slice_assertion(value_expr: &TokenStream, pattern: &PatternSlice) -> TokenStream { |
| 551 | let mut pattern_parts = Vec::new(); |
| 552 | let mut bindings_and_assertions = Vec::new(); |
| 553 | |
| 554 | for (i, elem) in pattern.elements.iter().enumerate() { |
| 555 | match elem { |
| 556 | Pattern::Range(PatternRange { |
| 557 | expr: syn::Expr::Range(r), |
| 558 | .. |
| 559 | }) if r.start.is_none() && r.end.is_none() => { |
| 560 | // RangeFull (..) in slice context is a rest pattern |
| 561 | pattern_parts.push(quote! { .. }); |
| 562 | } |
| 563 | Pattern::Wildcard(PatternWildcard { .. }) => { |
| 564 | // Wildcard pattern matches any single element without binding |
| 565 | pattern_parts.push(quote! { _ }); |
| 566 | } |
| 567 | _ => { |
| 568 | let binding = quote::format_ident!("__elem_{}", i); |
| 569 | pattern_parts.push(quote! { #binding }); |
| 570 | |
| 571 | let assertion = expand_pattern_assertion("e! { #binding }, elem); |
| 572 | bindings_and_assertions.push(assertion); |
| 573 | } |
| 574 | } |
| 575 | } |
| 576 | |
| 577 | // Convert Vec to slice for matching |
| 578 | let slice_expr = quote! { (#value_expr).as_slice() }; |
| 579 | |
| 580 | let error_push = generate_error_push( |
| 581 | proc_macro2::Span::call_site(), |
| 582 | quote!(format!("{:?}", &#value_expr)), |
| 583 | quote!(None), |
| 584 | pattern.node_id, |
| 585 | ); |
| 586 | |
| 587 | quote! { |
| 588 | match #slice_expr { |
| 589 | [#(#pattern_parts),*] => { |
| 590 | #(#bindings_and_assertions)* |
| 591 | } |
| 592 | _ => { |
| 593 | #error_push |
| 594 | } |
| 595 | } |
| 596 | } |
| 597 | } |
| 598 | |
| 599 | #[cfg(feature = "regex")] |
| 600 | /// Generate regex assertion with error collection |
no test coverage detected