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}