Skip to main content

ct_regex_internal/codegen/create_type/
regex.rs

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