| 823 | |
| 824 | impl<'a> SharedPrefixPlan<'a> { |
| 825 | fn try_new(variants: &[&'a VariantPlan], is_last: bool) -> Option<Self> { |
| 826 | if variants.len() < 2 { |
| 827 | return None; |
| 828 | } |
| 829 | // All variants must start with the same non-atom first field type. |
| 830 | let first_field = variants[0].fields.first()?; |
| 831 | if first_field.atom.is_some() { |
| 832 | return None; |
| 833 | } |
| 834 | let first_ty = &first_field.ty; |
| 835 | let prefix_ty_str = quote!(#first_ty).to_string(); |
| 836 | let all_share_prefix = variants.iter().all(|v| { |
| 837 | v.fields.first().is_some_and(|f| { |
| 838 | let ty = &f.ty; |
| 839 | f.atom.is_none() && quote!(#ty).to_string() == prefix_ty_str |
| 840 | }) |
| 841 | }); |
| 842 | if !all_share_prefix { |
| 843 | return None; |
| 844 | } |
| 845 | let mut atom_variants = Vec::new(); |
| 846 | let mut bare_variant = None; |
| 847 | for v in variants { |
| 848 | match v.fields.as_slice() { |
| 849 | [_prefix] => { |
| 850 | if bare_variant.is_some() { |
| 851 | return None; // two bare variants — ambiguous |
| 852 | } |
| 853 | bare_variant = Some(*v); |
| 854 | } |
| 855 | [_prefix, second] if second.atom.is_some() => { |
| 856 | atom_variants.push(*v); |
| 857 | } |
| 858 | _ => return None, // more complex structure — don't handle here |
| 859 | } |
| 860 | } |
| 861 | // Need at least one atom variant for this to be useful. |
| 862 | if atom_variants.is_empty() { |
| 863 | return None; |
| 864 | } |
| 865 | Some(Self { prefix_ty: first_field.ty.clone(), atom_variants, bare_variant, is_last }) |
| 866 | } |
| 867 | } |
| 868 | |
| 869 | impl<'a> Plan for SharedPrefixPlan<'a> { |