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

Function expand_map_assertion

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

Generate map assertion with error collection using duck typing Assumes map types have len() -> usize and get(&K) -> Option<&V> methods

(value_expr: &TokenStream, pattern: &PatternMap)

Source from the content-addressed store, hash-verified

665/// Generate map assertion with error collection using duck typing
666/// Assumes map types have len() -> usize and get(&K) -> Option<&V> methods
667fn expand_map_assertion(value_expr: &TokenStream, pattern: &PatternMap) -> TokenStream {
668 let entries = &pattern.entries;
669 let rest = pattern.rest;
670
671 // Use span from first entry or default span if empty
672 let map_span = entries
673 .first()
674 .map(|(key, _)| key.span())
675 .unwrap_or_else(proc_macro2::Span::call_site);
676
677 // Generate length check assertion for exact matching (when no rest pattern)
678 let len_check = if !rest {
679 let expected_len = entries.len();
680 let error_push = generate_error_push(
681 map_span,
682 quote!(format!("map with {} entries", (#value_expr).len())),
683 quote!(Some(format!("{} entries", #expected_len))),
684 pattern.node_id,
685 );
686 quote_spanned! {map_span=>
687 // Check exact length for maps without rest pattern
688 if (#value_expr).len() != #expected_len {
689 #error_push
690 }
691 }
692 } else {
693 quote! {}
694 };
695
696 // Generate key-value assertions
697 let key_value_assertions: Vec<TokenStream> = entries
698 .iter()
699 .map(|(key, value_pattern)| {
700 let key_str = quote! { #key }.to_string();
701
702 let span = key.span();
703 let pattern_assertion =
704 expand_pattern_assertion(&quote! { __map_value }, value_pattern);
705
706 let missing_key_error = generate_error_push(
707 span,
708 quote!("missing key".to_string()),
709 quote!(Some(format!("key present: {}", #key_str))),
710 pattern.node_id,
711 );
712
713 // Handle different key types for duck typing
714 let get_expr = if matches!(
715 key,
716 syn::Expr::Lit(syn::ExprLit {
717 lit: syn::Lit::Str(_),
718 ..
719 })
720 ) {
721 // For string literals, convert to String to match HashMap<String, V>
722 quote_spanned! {span=> (#value_expr).get(&(#key).to_string()) }
723 } else {
724 // For other expressions, try as-is

Callers 1

expand_pattern_assertionFunction · 0.85

Calls 4

generate_error_pushFunction · 0.85
expand_pattern_assertionFunction · 0.85
lenMethod · 0.80
spanMethod · 0.45

Tested by

no test coverage detected