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}