Skip to main content

ct_regex_internal/codegen/create_type/
regex.rs

1use proc_macro2::{Span, TokenStream};
2use quote::{format_ident, quote};
3use syn::{Ident, Visibility};
4
5use crate::codegen::{AnonRegexArgs, RegexArgs, TypeExpressions, capture, literal};
6
7pub fn make_regex(
8    RegexArgs {
9        vis,
10        name,
11        pat,
12        flags,
13    }: RegexArgs,
14    impl_anon: bool,
15) -> TokenStream {
16    #![allow(nonstandard_style)]
17    let fmt = {
    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, "fmt");
    _s
}quote!(::std::fmt);
18    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);
19    let Regex = {
    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, "Regex");
    _s
}quote!(::ct_regex::internal::expr::Regex);
20    let AnonRegex = {
    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, "AnonRegex");
    _s
}quote!(::ct_regex::internal::expr::AnonRegex);
21
22    let mod_name = match ::quote::__private::IdentFragmentAdapter(&&name) {
    arg =>
        ::quote::__private::mk_ident(&::alloc::__export::must_use({
                        ::alloc::fmt::format(format_args!("__regex_{0}", arg))
                    }), ::quote::__private::Option::None.or(arg.span())),
}format_ident!("__regex_{}", &name);
23
24    let pat_str = pat.value();
25
26    let doc = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("A macro-generated regular expression matching the pattern: `{0}` with flags: {1}. See the [`Regex`](::ct_regex::internal::expr::Regex) trait for associated matching and capturing functions.",
                pat_str, flags))
    })format!(
27        "A macro-generated regular expression matching the pattern: `{pat_str}` with flags: \
28        {flags}. See the [`Regex`](::ct_regex::internal::expr::Regex) trait for associated \
29        matching and capturing functions."
30    );
31
32    let mut config = flags.create_config();
33    config.unicode(false).utf8(false);
34    let TypeExpressions {
35        matcher: byte_matcher,
36        anchors: byte_anchors,
37        meta: byte_meta
38    } = TypeExpressions::parse_regex::<u8>(&name, &pat_str, &config);
39
40    config.unicode(true).utf8(true);
41    let TypeExpressions {
42        matcher: scalar_matcher,
43        anchors: scalar_anchors,
44        meta: mut scalar_meta
45    } = TypeExpressions::parse_regex::<char>(&name, &pat_str, &config);
46
47    match (&byte_meta, &scalar_meta) {
    (left_val, right_val) => {
        if !(*left_val == *right_val) {
            let kind = ::core::panicking::AssertKind::Eq;
            ::core::panicking::assert_failed(kind, &*left_val, &*right_val,
                ::core::option::Option::None);
        }
    }
};assert_eq!(byte_meta, scalar_meta);
48    let (captures_name, captures_len, captures_impl) = capture::impl_captures(
49        &name,
50        scalar_meta.take_groups()
51    );
52
53    let literal_impl = literal::impl_literals(scalar_meta);
54
55    let anon_impl = if impl_anon {
56        {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "impl");
    ::quote::ToTokens::to_tokens(&AnonRegex, &mut _s);
    ::quote::__private::push_lt(&mut _s);
    ::quote::__private::push_ident(&mut _s, "u8");
    ::quote::__private::push_comma(&mut _s);
    ::quote::ToTokens::to_tokens(&captures_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_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        ::quote::__private::TokenStream::new());
    ::quote::__private::push_ident(&mut _s, "impl");
    ::quote::ToTokens::to_tokens(&AnonRegex, &mut _s);
    ::quote::__private::push_lt(&mut _s);
    ::quote::__private::push_ident(&mut _s, "char");
    ::quote::__private::push_comma(&mut _s);
    ::quote::ToTokens::to_tokens(&captures_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_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        ::quote::__private::TokenStream::new());
    _s
}quote! {
57            impl #AnonRegex<u8, #captures_len> for #name {}
58
59            impl #AnonRegex<char, #captures_len> for #name {}
60        }
61    } else {
62        ::quote::__private::TokenStream::new()quote!()
63    };
64
65    {
    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_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "hidden");
                    _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, "allow");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "non_snake_case");
                    _s
                });
            _s
        });
    ::quote::__private::push_ident(&mut _s, "mod");
    ::quote::ToTokens::to_tokens(&mod_name, &mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::ToTokens::to_tokens(&literal_impl, &mut _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, "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, "Clone");
                            ::quote::__private::push_comma(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "Copy");
                            _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_semi(&mut _s);
            ::quote::__private::push_ident(&mut _s, "impl");
            ::quote::ToTokens::to_tokens(&Regex, &mut _s);
            ::quote::__private::push_lt(&mut _s);
            ::quote::__private::push_ident(&mut _s, "u8");
            ::quote::__private::push_comma(&mut _s);
            ::quote::ToTokens::to_tokens(&captures_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_group(&mut _s,
                ::quote::__private::Delimiter::Brace,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "type");
                    ::quote::__private::push_ident(&mut _s, "Pattern");
                    ::quote::__private::push_eq(&mut _s);
                    ::quote::ToTokens::to_tokens(&byte_matcher, &mut _s);
                    ::quote::__private::push_semi(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "type");
                    ::quote::__private::push_ident(&mut _s, "Anchors");
                    ::quote::__private::push_eq(&mut _s);
                    ::quote::ToTokens::to_tokens(&byte_anchors, &mut _s);
                    ::quote::__private::push_semi(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "type");
                    ::quote::__private::push_ident(&mut _s, "Capture");
                    ::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_eq(&mut _s);
                    ::quote::ToTokens::to_tokens(&captures_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_semi(&mut _s);
                    _s
                });
            ::quote::__private::push_ident(&mut _s, "impl");
            ::quote::ToTokens::to_tokens(&Regex, &mut _s);
            ::quote::__private::push_lt(&mut _s);
            ::quote::__private::push_ident(&mut _s, "char");
            ::quote::__private::push_comma(&mut _s);
            ::quote::ToTokens::to_tokens(&captures_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_group(&mut _s,
                ::quote::__private::Delimiter::Brace,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "type");
                    ::quote::__private::push_ident(&mut _s, "Pattern");
                    ::quote::__private::push_eq(&mut _s);
                    ::quote::ToTokens::to_tokens(&scalar_matcher, &mut _s);
                    ::quote::__private::push_semi(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "type");
                    ::quote::__private::push_ident(&mut _s, "Anchors");
                    ::quote::__private::push_eq(&mut _s);
                    ::quote::ToTokens::to_tokens(&scalar_anchors, &mut _s);
                    ::quote::__private::push_semi(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "type");
                    ::quote::__private::push_ident(&mut _s, "Capture");
                    ::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_eq(&mut _s);
                    ::quote::ToTokens::to_tokens(&captures_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_semi(&mut _s);
                    _s
                });
            ::quote::ToTokens::to_tokens(&anon_impl, &mut _s);
            ::quote::__private::push_ident(&mut _s, "impl");
            ::quote::ToTokens::to_tokens(&fmt, &mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Debug");
            ::quote::__private::push_ident(&mut _s, "for");
            ::quote::ToTokens::to_tokens(&name, &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, "fmt");
                    ::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");
                            ::quote::__private::push_comma(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "f");
                            ::quote::__private::push_colon(&mut _s);
                            ::quote::__private::push_and(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "mut");
                            ::quote::ToTokens::to_tokens(&fmt, &mut _s);
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "Formatter");
                            ::quote::__private::push_lt(&mut _s);
                            ::quote::__private::push_lifetime(&mut _s, "\'_");
                            ::quote::__private::push_gt(&mut _s);
                            _s
                        });
                    ::quote::__private::push_rarrow(&mut _s);
                    ::quote::ToTokens::to_tokens(&fmt, &mut _s);
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "Result");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Brace,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_ident(&mut _s, "write");
                            ::quote::__private::push_bang(&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, "f");
                                    ::quote::__private::push_comma(&mut _s);
                                    ::quote::__private::parse(&mut _s, "\"/{:?}/\"");
                                    ::quote::__private::push_comma(&mut _s);
                                    ::quote::__private::push_lt(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "Self");
                                    ::quote::__private::push_ident(&mut _s, "as");
                                    ::quote::ToTokens::to_tokens(&Regex, &mut _s);
                                    ::quote::__private::push_lt(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "char");
                                    ::quote::__private::push_comma(&mut _s);
                                    ::quote::ToTokens::to_tokens(&captures_len, &mut _s);
                                    ::quote::__private::push_shr(&mut _s);
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "Pattern");
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "default");
                                    ::quote::__private::push_group(&mut _s,
                                        ::quote::__private::Delimiter::Parenthesis,
                                        ::quote::__private::TokenStream::new());
                                    _s
                                });
                            _s
                        });
                    _s
                });
            ::quote::ToTokens::to_tokens(&captures_impl, &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, "doc");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "inline");
                    _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, "allow");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "unused");
                    _s
                });
            _s
        });
    ::quote::ToTokens::to_tokens(&vis, &mut _s);
    ::quote::__private::push_ident(&mut _s, "use");
    ::quote::ToTokens::to_tokens(&mod_name, &mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::ToTokens::to_tokens(&name, &mut _s);
            ::quote::__private::push_comma(&mut _s);
            ::quote::ToTokens::to_tokens(&captures_name, &mut _s);
            _s
        });
    ::quote::__private::push_semi(&mut _s);
    _s
}quote! {
66        #[doc(hidden)]
67        #[allow(non_snake_case)]
68        mod #mod_name {
69            #literal_impl
70
71            #[doc = #doc]
72            #[derive(Clone, Copy)]
73            pub struct #name;
74
75            impl #Regex<u8, #captures_len> for #name {
76                type Pattern = #byte_matcher;
77                type Anchors = #byte_anchors;
78                type Capture<'a, S: #HaystackSlice<'a>> = #captures_name<'a, S>;
79            }
80
81            impl #Regex<char, #captures_len> for #name {
82                type Pattern = #scalar_matcher;
83                type Anchors = #scalar_anchors;
84                type Capture<'a, S: #HaystackSlice<'a>> = #captures_name<'a, S>;
85            }
86
87            #anon_impl
88
89            impl #fmt::Debug for #name {
90                fn fmt(&self, f: &mut #fmt::Formatter<'_>) -> #fmt::Result {
91                    write!(f, "/{:?}/", <Self as #Regex<char, #captures_len>>::Pattern::default())
92                }
93            }
94
95            #captures_impl
96        }
97
98        #[doc(inline)]
99        #[allow(unused)]
100        #vis use #mod_name::{#name, #captures_name};
101    }
102}
103
104pub fn make_anon_regex(AnonRegexArgs { pat, flags }: AnonRegexArgs) -> TokenStream {
105    let impl_tokens = make_regex(
106        RegexArgs {
107            vis: Visibility::Inherited,
108            name: Ident::new("__AnonRegex", Span::call_site()),
109            pat,
110            flags,
111        },
112        true,
113    );
114    {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::ToTokens::to_tokens(&impl_tokens, &mut _s);
            ::quote::__private::push_ident(&mut _s, "__AnonRegex");
            _s
        });
    _s
}quote! {
115        {
116            #impl_tokens
117
118            __AnonRegex
119        }
120    }
121}