Skip to main content

ct_regex_internal/codegen/create_type/
capture.rs

1use proc_macro2::{Literal, Span, TokenStream};
2use quote::{format_ident, quote};
3use syn::Ident;
4
5use crate::codegen::Group;
6
7pub(crate) fn impl_captures(regex_name: &Ident, groups: Vec<Group>) -> (Ident, Literal, TokenStream) {
8    #![allow(nonstandard_style)]
9    let Capture = {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "ct_regex");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "internal");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "expr");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Capture");
    _s
}quote!(::ct_regex::internal::expr::Capture);
10    let FromRanges = {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "ct_regex");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "internal");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "expr");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "FromRanges");
    _s
}quote!(::ct_regex::internal::expr::FromRanges);
11    let HaystackSlice = {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "ct_regex");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "internal");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "haystack");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "HaystackSlice");
    _s
}quote!(::ct_regex::internal::haystack::HaystackSlice);
12    let Range = {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "std");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "ops");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Range");
    ::quote::__private::push_lt(&mut _s);
    ::quote::__private::push_ident(&mut _s, "usize");
    ::quote::__private::push_gt(&mut _s);
    _s
}quote!(::std::ops::Range<usize>);
13    let Option = {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "std");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "option");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Option");
    _s
}quote!(::std::option::Option);
14    let PhantomData = {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "std");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "marker");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "PhantomData");
    _s
}quote!(::std::marker::PhantomData);
15
16    let len_usize = groups.len();
17
18    let name = match ::quote::__private::IdentFragmentAdapter(&regex_name) {
    arg =>
        ::quote::__private::mk_ident(&::alloc::__export::must_use({
                        ::alloc::fmt::format(format_args!("{0}Capture", arg))
                    }), ::quote::__private::Option::None.or(arg.span())),
}format_ident!("{}Capture", regex_name);
19    let len = Literal::usize_unsuffixed(len_usize);
20
21    let doc = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("A macro-generated type that holds {0} captures for the associated regex, [`{1}`]. If present, named groups can be retrieved through their associated method.\n\nCapture types include methods to retrieve individual captures as a slice of the original haystack, or as the underlying [`Range<usize>`](::std::range::Range), which can be used to manually slice the haystack (without risk of panicking in the case of `&str`).\n\nAs is common with regular expressions, group `0` refers to the whole match (and is therefore aliased as [`{2}::whole_match`]).",
                len_usize, regex_name, name))
    })format!(
22        "A macro-generated type that holds {len_usize} captures for the associated regex, \
23        [`{regex_name}`]. If present, named groups can be retrieved through their associated \
24        method.\n\n\
25        Capture types include methods to retrieve individual captures as a slice of the original \
26        haystack, or as the underlying [`Range<usize>`](::std::range::Range), which can be used \
27        to manually slice the haystack (without risk of panicking in the case of `&str`).\n\n\
28        As is common with regular expressions, group `0` refers to the whole match (and is \
29        therefore aliased as [`{name}::whole_match`])."
30    );
31
32    if !!groups.is_empty() {
    ::core::panicking::panic("assertion failed: !groups.is_empty()")
};assert!(!groups.is_empty());
33
34    let inner = groups.iter().map(|cap| {
35        if cap.required {
36            {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&Range, &mut _s);
    _s
}quote!(#Range)
37        } else {
38            {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&Option, &mut _s);
    ::quote::__private::push_lt(&mut _s);
    ::quote::ToTokens::to_tokens(&Range, &mut _s);
    ::quote::__private::push_gt(&mut _s);
    _s
}quote!(#Option<#Range>)
39        }
40    });
41
42    let numbered_groups = groups.iter()
43        .enumerate()
44        .map(|(index, cap)| impl_capture_getters(index, cap, match ::quote::__private::IdentFragmentAdapter(&index) {
    arg =>
        ::quote::__private::mk_ident(&::alloc::__export::must_use({
                        ::alloc::fmt::format(format_args!("cap_{0}", arg))
                    }), ::quote::__private::Option::None.or(arg.span())),
}format_ident!("cap_{}", index)));
45
46    let named_groups = groups.iter()
47        .enumerate()
48        .filter_map(|(index, cap)| {
49            cap.name.as_ref().map(|cap_name| {
50                impl_capture_getters(index, cap, Ident::new(cap_name, Span::call_site()))
51            })
52        });
53
54    let capture_destructure = (0..groups.len()).map(|i| match ::quote::__private::IdentFragmentAdapter(&i) {
    arg =>
        ::quote::__private::mk_ident(&::alloc::__export::must_use({
                        ::alloc::fmt::format(format_args!("c{0}", arg))
                    }), ::quote::__private::Option::None.or(arg.span())),
}format_ident!("c{}", i));
55
56    let capture_constructor = groups.iter().enumerate().map(|(index, cap)| {
57        let ident = match ::quote::__private::IdentFragmentAdapter(&index) {
    arg =>
        ::quote::__private::mk_ident(&::alloc::__export::must_use({
                        ::alloc::fmt::format(format_args!("c{0}", arg))
                    }), ::quote::__private::Option::None.or(arg.span())),
}format_ident!("c{}", index);
58        if cap.required {
59            {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&ident, &mut _s);
    ::quote::__private::push_question(&mut _s);
    _s
}quote!(#ident?)
60        } else {
61            {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&ident, &mut _s);
    _s
}quote!(#ident)
62        }
63    });
64
65    // TODO: Manual debug implementation
66
67    let captures_impl = {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_pound(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Bracket,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "doc");
            ::quote::__private::push_eq(&mut _s);
            ::quote::ToTokens::to_tokens(&doc, &mut _s);
            _s
        });
    ::quote::__private::push_pound(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Bracket,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "derive");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "Debug");
                    ::quote::__private::push_comma(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "Clone");
                    _s
                });
            _s
        });
    ::quote::__private::push_ident(&mut _s, "pub");
    ::quote::__private::push_ident(&mut _s, "struct");
    ::quote::ToTokens::to_tokens(&name, &mut _s);
    ::quote::__private::push_lt(&mut _s);
    ::quote::__private::push_lifetime(&mut _s, "\'a");
    ::quote::__private::push_comma(&mut _s);
    ::quote::__private::push_ident(&mut _s, "S");
    ::quote::__private::push_colon(&mut _s);
    ::quote::ToTokens::to_tokens(&HaystackSlice, &mut _s);
    ::quote::__private::push_lt(&mut _s);
    ::quote::__private::push_lifetime(&mut _s, "\'a");
    ::quote::__private::push_shr(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "S");
            ::quote::__private::push_comma(&mut _s);
            {
                use ::quote::__private::ext::*;
                let mut _first = true;
                let has_iter = ::quote::__private::HasIterator::<false>;
                #[allow(unused_mut)]
                let (mut inner, i) = inner.quote_into_iter();
                let has_iter = has_iter | i;
                <_ as
                        ::quote::__private::CheckHasIterator<true>>::check(has_iter);
                while true {
                    let inner =
                        match inner.next() {
                            Some(_x) => ::quote::__private::RepInterp(_x),
                            None => break,
                        };
                    if !_first { ::quote::__private::push_comma(&mut _s); }
                    _first = false;
                    ::quote::ToTokens::to_tokens(&inner, &mut _s);
                }
            }
            ::quote::__private::push_comma(&mut _s);
            ::quote::ToTokens::to_tokens(&PhantomData, &mut _s);
            ::quote::__private::push_lt(&mut _s);
            ::quote::__private::push_and(&mut _s);
            ::quote::__private::push_lifetime(&mut _s, "\'a");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                ::quote::__private::TokenStream::new());
            ::quote::__private::push_gt(&mut _s);
            ::quote::__private::push_comma(&mut _s);
            _s
        });
    ::quote::__private::push_semi(&mut _s);
    ::quote::__private::push_ident(&mut _s, "impl");
    ::quote::__private::push_lt(&mut _s);
    ::quote::__private::push_lifetime(&mut _s, "\'a");
    ::quote::__private::push_comma(&mut _s);
    ::quote::__private::push_ident(&mut _s, "S");
    ::quote::__private::push_colon(&mut _s);
    ::quote::ToTokens::to_tokens(&HaystackSlice, &mut _s);
    ::quote::__private::push_lt(&mut _s);
    ::quote::__private::push_lifetime(&mut _s, "\'a");
    ::quote::__private::push_shr(&mut _s);
    ::quote::ToTokens::to_tokens(&name, &mut _s);
    ::quote::__private::push_lt(&mut _s);
    ::quote::__private::push_lifetime(&mut _s, "\'a");
    ::quote::__private::push_comma(&mut _s);
    ::quote::__private::push_ident(&mut _s, "S");
    ::quote::__private::push_gt(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            {
                use ::quote::__private::ext::*;
                let has_iter = ::quote::__private::HasIterator::<false>;
                #[allow(unused_mut)]
                let (mut numbered_groups, i) =
                    numbered_groups.quote_into_iter();
                let has_iter = has_iter | i;
                <_ as
                        ::quote::__private::CheckHasIterator<true>>::check(has_iter);
                while true {
                    let numbered_groups =
                        match numbered_groups.next() {
                            Some(_x) => ::quote::__private::RepInterp(_x),
                            None => break,
                        };
                    ::quote::ToTokens::to_tokens(&numbered_groups, &mut _s);
                }
            }
            {
                use ::quote::__private::ext::*;
                let has_iter = ::quote::__private::HasIterator::<false>;
                #[allow(unused_mut)]
                let (mut named_groups, i) = named_groups.quote_into_iter();
                let has_iter = has_iter | i;
                <_ as
                        ::quote::__private::CheckHasIterator<true>>::check(has_iter);
                while true {
                    let named_groups =
                        match named_groups.next() {
                            Some(_x) => ::quote::__private::RepInterp(_x),
                            None => break,
                        };
                    ::quote::ToTokens::to_tokens(&named_groups, &mut _s);
                }
            }
            _s
        });
    ::quote::__private::push_ident(&mut _s, "impl");
    ::quote::__private::push_lt(&mut _s);
    ::quote::__private::push_lifetime(&mut _s, "\'a");
    ::quote::__private::push_comma(&mut _s);
    ::quote::__private::push_ident(&mut _s, "S");
    ::quote::__private::push_colon(&mut _s);
    ::quote::ToTokens::to_tokens(&HaystackSlice, &mut _s);
    ::quote::__private::push_lt(&mut _s);
    ::quote::__private::push_lifetime(&mut _s, "\'a");
    ::quote::__private::push_shr(&mut _s);
    ::quote::ToTokens::to_tokens(&Capture, &mut _s);
    ::quote::__private::push_lt(&mut _s);
    ::quote::__private::push_lifetime(&mut _s, "\'a");
    ::quote::__private::push_comma(&mut _s);
    ::quote::__private::push_ident(&mut _s, "S");
    ::quote::__private::push_gt(&mut _s);
    ::quote::__private::push_ident(&mut _s, "for");
    ::quote::ToTokens::to_tokens(&name, &mut _s);
    ::quote::__private::push_lt(&mut _s);
    ::quote::__private::push_lifetime(&mut _s, "\'a");
    ::quote::__private::push_comma(&mut _s);
    ::quote::__private::push_ident(&mut _s, "S");
    ::quote::__private::push_gt(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "fn");
            ::quote::__private::push_ident(&mut _s, "whole_match_range");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_and(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "self");
                    _s
                });
            ::quote::__private::push_rarrow(&mut _s);
            ::quote::ToTokens::to_tokens(&Range, &mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Brace,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "self");
                    ::quote::__private::push_dot(&mut _s);
                    ::quote::__private::parse(&mut _s, "1");
                    ::quote::__private::push_dot(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "clone");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        ::quote::__private::TokenStream::new());
                    _s
                });
            ::quote::__private::push_ident(&mut _s, "fn");
            ::quote::__private::push_ident(&mut _s, "whole_match");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_and(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "self");
                    _s
                });
            ::quote::__private::push_rarrow(&mut _s);
            ::quote::__private::push_ident(&mut _s, "S");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Brace,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "self");
                    ::quote::__private::push_dot(&mut _s);
                    ::quote::__private::parse(&mut _s, "0");
                    ::quote::__private::push_dot(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "slice_with");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_ident(&mut _s, "self");
                            ::quote::__private::push_dot(&mut _s);
                            ::quote::__private::push_ident(&mut _s,
                                "whole_match_range");
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                ::quote::__private::TokenStream::new());
                            _s
                        });
                    _s
                });
            _s
        });
    ::quote::__private::push_ident(&mut _s, "impl");
    ::quote::__private::push_lt(&mut _s);
    ::quote::__private::push_lifetime(&mut _s, "\'a");
    ::quote::__private::push_comma(&mut _s);
    ::quote::__private::push_ident(&mut _s, "S");
    ::quote::__private::push_colon(&mut _s);
    ::quote::ToTokens::to_tokens(&HaystackSlice, &mut _s);
    ::quote::__private::push_lt(&mut _s);
    ::quote::__private::push_lifetime(&mut _s, "\'a");
    ::quote::__private::push_shr(&mut _s);
    ::quote::ToTokens::to_tokens(&FromRanges, &mut _s);
    ::quote::__private::push_lt(&mut _s);
    ::quote::__private::push_lifetime(&mut _s, "\'a");
    ::quote::__private::push_comma(&mut _s);
    ::quote::__private::push_ident(&mut _s, "S");
    ::quote::__private::push_comma(&mut _s);
    ::quote::ToTokens::to_tokens(&len, &mut _s);
    ::quote::__private::push_gt(&mut _s);
    ::quote::__private::push_ident(&mut _s, "for");
    ::quote::ToTokens::to_tokens(&name, &mut _s);
    ::quote::__private::push_lt(&mut _s);
    ::quote::__private::push_lifetime(&mut _s, "\'a");
    ::quote::__private::push_comma(&mut _s);
    ::quote::__private::push_ident(&mut _s, "S");
    ::quote::__private::push_gt(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "fn");
            ::quote::__private::push_ident(&mut _s, "from_ranges");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "ranges");
                    ::quote::__private::push_colon(&mut _s);
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Bracket,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::ToTokens::to_tokens(&Option, &mut _s);
                            ::quote::__private::push_lt(&mut _s);
                            ::quote::ToTokens::to_tokens(&Range, &mut _s);
                            ::quote::__private::push_gt(&mut _s);
                            ::quote::__private::push_semi(&mut _s);
                            ::quote::ToTokens::to_tokens(&len, &mut _s);
                            _s
                        });
                    ::quote::__private::push_comma(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "hay");
                    ::quote::__private::push_colon(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "S");
                    ::quote::__private::push_comma(&mut _s);
                    _s
                });
            ::quote::__private::push_rarrow(&mut _s);
            ::quote::ToTokens::to_tokens(&Option, &mut _s);
            ::quote::__private::push_lt(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Self");
            ::quote::__private::push_gt(&mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Brace,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "let");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Bracket,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            {
                                use ::quote::__private::ext::*;
                                let mut _first = true;
                                let has_iter = ::quote::__private::HasIterator::<false>;
                                #[allow(unused_mut)]
                                let (mut capture_destructure, i) =
                                    capture_destructure.quote_into_iter();
                                let has_iter = has_iter | i;
                                <_ as
                                        ::quote::__private::CheckHasIterator<true>>::check(has_iter);
                                while true {
                                    let capture_destructure =
                                        match capture_destructure.next() {
                                            Some(_x) => ::quote::__private::RepInterp(_x),
                                            None => break,
                                        };
                                    if !_first { ::quote::__private::push_comma(&mut _s); }
                                    _first = false;
                                    ::quote::ToTokens::to_tokens(&capture_destructure, &mut _s);
                                }
                            }
                            _s
                        });
                    ::quote::__private::push_eq(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "ranges");
                    ::quote::__private::push_semi(&mut _s);
                    ::quote::ToTokens::to_tokens(&Option, &mut _s);
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "Some");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_ident(&mut _s, "Self");
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                {
                                    let mut _s = ::quote::__private::TokenStream::new();
                                    ::quote::__private::push_ident(&mut _s, "hay");
                                    ::quote::__private::push_comma(&mut _s);
                                    {
                                        use ::quote::__private::ext::*;
                                        let mut _first = true;
                                        let has_iter = ::quote::__private::HasIterator::<false>;
                                        #[allow(unused_mut)]
                                        let (mut capture_constructor, i) =
                                            capture_constructor.quote_into_iter();
                                        let has_iter = has_iter | i;
                                        <_ as
                                                ::quote::__private::CheckHasIterator<true>>::check(has_iter);
                                        while true {
                                            let capture_constructor =
                                                match capture_constructor.next() {
                                                    Some(_x) => ::quote::__private::RepInterp(_x),
                                                    None => break,
                                                };
                                            if !_first { ::quote::__private::push_comma(&mut _s); }
                                            _first = false;
                                            ::quote::ToTokens::to_tokens(&capture_constructor, &mut _s);
                                        }
                                    }
                                    ::quote::__private::push_comma(&mut _s);
                                    ::quote::ToTokens::to_tokens(&PhantomData, &mut _s);
                                    ::quote::__private::push_comma(&mut _s);
                                    _s
                                });
                            _s
                        });
                    _s
                });
            _s
        });
    _s
}quote! {
68        #[doc = #doc]
69        #[derive(Debug, Clone)]
70        pub struct #name<'a, S: #HaystackSlice<'a>>(
71            S,
72            #(#inner),*,
73            #PhantomData<&'a ()>,
74        );
75
76        impl<'a, S: #HaystackSlice<'a>> #name<'a, S> {
77            #(#numbered_groups)*
78
79            #(#named_groups)*
80        }
81
82        impl<'a, S: #HaystackSlice<'a>> #Capture<'a, S> for #name<'a, S> {
83            fn whole_match_range(&self) -> #Range {
84                self.1.clone()
85            }
86
87            fn whole_match(&self) -> S {
88                self.0.slice_with(self.whole_match_range())
89            }
90        }
91
92        impl<'a, S: #HaystackSlice<'a>> #FromRanges<'a, S, #len> for #name<'a, S> {
93            fn from_ranges(
94                ranges: [#Option<#Range>; #len],
95                hay: S,
96            ) -> #Option<Self> {
97                let [#(#capture_destructure),*] = ranges;
98                #Option::Some(Self(
99                    hay,
100                    #(#capture_constructor),*,
101                    #PhantomData,
102                ))
103            }
104        }
105    };
106
107    (name, len, captures_impl)
108}
109
110pub(crate) fn impl_capture_getters(index: usize, cap: &Group, cap_name: Ident) -> TokenStream {
111    #![allow(nonstandard_style)]
112    let Range = {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "std");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "ops");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Range");
    ::quote::__private::push_lt(&mut _s);
    ::quote::__private::push_ident(&mut _s, "usize");
    ::quote::__private::push_gt(&mut _s);
    _s
}quote!(::std::ops::Range<usize>);
113    let Option = {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "std");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "option");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Option");
    _s
}quote!(::std::option::Option);
114
115    let index = index + 1;
116    let cap_name_full = match ::quote::__private::IdentFragmentAdapter(&cap_name) {
    arg =>
        ::quote::__private::mk_ident(&::alloc::__export::must_use({
                        ::alloc::fmt::format(format_args!("{0}_range", arg))
                    }), ::quote::__private::Option::None.or(arg.span())),
}format_ident!("{}_range", cap_name);
117    let index_name = Literal::usize_unsuffixed(index);
118
119    if cap.required {
120        {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "pub");
    ::quote::__private::push_ident(&mut _s, "fn");
    ::quote::ToTokens::to_tokens(&cap_name, &mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_and(&mut _s);
            ::quote::__private::push_ident(&mut _s, "self");
            _s
        });
    ::quote::__private::push_rarrow(&mut _s);
    ::quote::__private::push_ident(&mut _s, "S");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "self");
            ::quote::__private::push_dot(&mut _s);
            ::quote::__private::parse(&mut _s, "0");
            ::quote::__private::push_dot(&mut _s);
            ::quote::__private::push_ident(&mut _s, "slice_with");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "self");
                    ::quote::__private::push_dot(&mut _s);
                    ::quote::ToTokens::to_tokens(&cap_name_full, &mut _s);
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        ::quote::__private::TokenStream::new());
                    _s
                });
            _s
        });
    ::quote::__private::push_ident(&mut _s, "pub");
    ::quote::__private::push_ident(&mut _s, "fn");
    ::quote::ToTokens::to_tokens(&cap_name_full, &mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_and(&mut _s);
            ::quote::__private::push_ident(&mut _s, "self");
            _s
        });
    ::quote::__private::push_rarrow(&mut _s);
    ::quote::ToTokens::to_tokens(&Range, &mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "self");
            ::quote::__private::push_dot(&mut _s);
            ::quote::ToTokens::to_tokens(&index_name, &mut _s);
            ::quote::__private::push_dot(&mut _s);
            ::quote::__private::push_ident(&mut _s, "clone");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                ::quote::__private::TokenStream::new());
            _s
        });
    _s
}quote! {
121            pub fn #cap_name(&self) -> S {
122                self.0.slice_with(self.#cap_name_full())
123            }
124
125            pub fn #cap_name_full(&self) -> #Range {
126                self.#index_name.clone()
127            }
128        }
129    } else {
130        {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "pub");
    ::quote::__private::push_ident(&mut _s, "fn");
    ::quote::ToTokens::to_tokens(&cap_name, &mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_and(&mut _s);
            ::quote::__private::push_ident(&mut _s, "self");
            _s
        });
    ::quote::__private::push_rarrow(&mut _s);
    ::quote::ToTokens::to_tokens(&Option, &mut _s);
    ::quote::__private::push_lt(&mut _s);
    ::quote::__private::push_ident(&mut _s, "S");
    ::quote::__private::push_gt(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "self");
            ::quote::__private::push_dot(&mut _s);
            ::quote::ToTokens::to_tokens(&cap_name_full, &mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                ::quote::__private::TokenStream::new());
            ::quote::__private::push_dot(&mut _s);
            ::quote::__private::push_ident(&mut _s, "map");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_or(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "r");
                    ::quote::__private::push_or(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "self");
                    ::quote::__private::push_dot(&mut _s);
                    ::quote::__private::parse(&mut _s, "0");
                    ::quote::__private::push_dot(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "slice_with");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_ident(&mut _s, "r");
                            _s
                        });
                    _s
                });
            _s
        });
    ::quote::__private::push_ident(&mut _s, "pub");
    ::quote::__private::push_ident(&mut _s, "fn");
    ::quote::ToTokens::to_tokens(&cap_name_full, &mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_and(&mut _s);
            ::quote::__private::push_ident(&mut _s, "self");
            _s
        });
    ::quote::__private::push_rarrow(&mut _s);
    ::quote::ToTokens::to_tokens(&Option, &mut _s);
    ::quote::__private::push_lt(&mut _s);
    ::quote::ToTokens::to_tokens(&Range, &mut _s);
    ::quote::__private::push_gt(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "self");
            ::quote::__private::push_dot(&mut _s);
            ::quote::ToTokens::to_tokens(&index_name, &mut _s);
            ::quote::__private::push_dot(&mut _s);
            ::quote::__private::push_ident(&mut _s, "clone");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                ::quote::__private::TokenStream::new());
            _s
        });
    _s
}quote! {
131            pub fn #cap_name(&self) -> #Option<S> {
132                self.#cap_name_full().map(|r| self.0.slice_with(r))
133            }
134
135            pub fn #cap_name_full(&self) -> #Option<#Range> {
136                self.#index_name.clone()
137            }
138        }
139    }
140}