1use proc_macro2::{Span, TokenStream};
2use quote::quote;
3use syn::{Ident, Visibility};
4
5use crate::codegen::{AnonRegexArgs, RegexArgs, capture, parse};
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 Haystack = {
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, "Haystack");
_s
}quote!(::ct_regex::internal::haystack::Haystack);
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 pat_str = pat.value();
23
24 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!(
25 "A macro-generated regular expression matching the pattern: `{pat_str}` with flags: \
26 {flags}. See the [`Regex`](::ct_regex::internal::expr::Regex) trait for associated \
27 matching and capturing functions."
28 );
30
31 let mut config = flags.create_config();
32 config.unicode(false).utf8(false);
33
34 let (type_expr_byte, groups) = parse::parse_regex::<u8>(&pat_str, &config);
35
36 config.unicode(true).utf8(true);
37
38 let (type_expr_scalar, _) = parse::parse_regex::<char>(&pat_str, &config);
39
40 let (captures_name, captures_len, captures_impl) = capture::impl_captures(&vis, &name, groups);
41
42 let anon_impl = if impl_anon {
43 {
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! {
44 impl #AnonRegex<u8, #captures_len> for #name {}
45
46 impl #AnonRegex<char, #captures_len> for #name {}
47 }
48 } else {
49 ::quote::__private::TokenStream::new()quote!()
50 };
51
52 {
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::ToTokens::to_tokens(&vis, &mut _s);
::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(&type_expr_byte, &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, "H");
::quote::__private::push_colon(&mut _s);
::quote::ToTokens::to_tokens(&Haystack, &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, "H");
::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(&type_expr_scalar, &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, "H");
::quote::__private::push_colon(&mut _s);
::quote::ToTokens::to_tokens(&Haystack, &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, "H");
::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! {
53 #[doc = #doc]
54 #vis struct #name;
55
56 impl #Regex<u8, #captures_len> for #name {
57 type Pattern = #type_expr_byte;
58
59 type Capture<'a, H: #Haystack<'a>> = #captures_name<'a, H>;
60 }
61
62 impl #Regex<char, #captures_len> for #name {
63 type Pattern = #type_expr_scalar;
64 type Capture<'a, H: #Haystack<'a>> = #captures_name<'a, H>;
65 }
66
67 #anon_impl
68
69 impl #fmt::Debug for #name {
70 fn fmt(&self, f: &mut #fmt::Formatter<'_>) -> #fmt::Result {
71 write!(f, "/{:?}/", <Self as #Regex<char, #captures_len>>::Pattern::default())
72 }
73 }
74
75 #captures_impl
76 }
77}
78
79pub fn make_anon_regex(AnonRegexArgs { pat, flags }: AnonRegexArgs) -> TokenStream {
80 let impl_tokens = make_regex(
81 RegexArgs {
82 vis: Visibility::Inherited,
83 name: Ident::new("__AnonRegex", Span::call_site()),
84 pat,
85 flags,
86 },
87 true
88 );
89 {
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! {
90 {
91 #impl_tokens
92
93 __AnonRegex
94 }
95 }
96}