ct_regex_internal/codegen/create_type/
parse.rs1use proc_macro2::TokenStream;
2use quote::quote;
3use regex_syntax::hir::{Capture, Hir, HirKind, Look, Properties};
4use syn::Ident;
5
6use crate::codegen::{CodegenItem, ConfigExt, ExprMetadata, IntoMatcherExpr, classes};
7
8#[derive(#[automatically_derived]
impl ::core::fmt::Debug for TypeExpressions {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field3_finish(f,
"TypeExpressions", "matcher", &self.matcher, "anchors",
&self.anchors, "meta", &&self.meta)
}
}Debug, #[automatically_derived]
impl ::core::clone::Clone for TypeExpressions {
#[inline]
fn clone(&self) -> TypeExpressions {
TypeExpressions {
matcher: ::core::clone::Clone::clone(&self.matcher),
anchors: ::core::clone::Clone::clone(&self.anchors),
meta: ::core::clone::Clone::clone(&self.meta),
}
}
}Clone)]
9pub(crate) struct TypeExpressions {
10 pub matcher: TokenStream,
11 pub anchors: TokenStream,
12 pub meta: ExprMetadata,
13}
14
15impl TypeExpressions {
16 pub fn parse_regex<I: CodegenItem>(name: &Ident, pat: &str, config: &ConfigExt) -> TypeExpressions {
17 let mut ast = config.ast.build()
18 .parse(pat)
19 .expect("failed to parse regex");
20
21 if !config.complex_classes {
22 classes::simplify_classes(&mut ast);
23 }
24
25 let hir = config.hir.build()
26 .translate(pat, &ast)
27 .expect("failed to parse regex");
28
29 TypeExpressions::create::<I>(hir, name)
30 }
31
32 pub fn create<I: CodegenItem>(hir: Hir, name: &Ident) -> TypeExpressions {
33 let mut meta = ExprMetadata::new(name.clone());
34 let anchors = TypeExpressions::create_anchor_expression(hir.properties());
35
36 TypeExpressions {
37 matcher: Self::remove_redundant_lookarounds(hir).into_matcher_expr::<I>(&mut meta),
38 anchors,
39 meta
40 }
41 }
42
43 pub fn create_anchor_expression(props: &Properties) -> TokenStream {
44 let mut anchors = Vec::new();
45
46 if props.look_set_prefix().contains(Look::Start) {
47 anchors.push({
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, "anchor");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "Start");
_s
}quote!(::ct_regex::internal::anchor::Start));
48 }
49 if let Some(min) = props.minimum_len() && min != 0 {
50 anchors.push({
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, "anchor");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "MinLen");
::quote::__private::push_lt(&mut _s);
::quote::ToTokens::to_tokens(&min, &mut _s);
::quote::__private::push_gt(&mut _s);
_s
}quote!(::ct_regex::internal::anchor::MinLen<#min>));
51 }
52 if let Some(max) = props.maximum_len() {
53 if props.look_set_suffix().contains(Look::End) {
54 anchors.push({
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, "anchor");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "EndAndMaxLen");
::quote::__private::push_lt(&mut _s);
::quote::ToTokens::to_tokens(&max, &mut _s);
::quote::__private::push_gt(&mut _s);
_s
}quote!(::ct_regex::internal::anchor::EndAndMaxLen<#max>));
55 } else {
56 anchors.push({
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, "anchor");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "MaxLen");
::quote::__private::push_lt(&mut _s);
::quote::ToTokens::to_tokens(&max, &mut _s);
::quote::__private::push_gt(&mut _s);
_s
}quote!(::ct_regex::internal::anchor::MaxLen<#max>));
57 }
58 }
59
60 match &anchors[..] {
61 [] => {
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, "anchor");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "AnchorNone");
_s
}quote!(::ct_regex::internal::anchor::AnchorNone),
62 [a] => {
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&a, &mut _s);
_s
}quote!(#a),
63 [a, b] => {
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, "anchor");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "AnchorPair");
::quote::__private::push_lt(&mut _s);
::quote::ToTokens::to_tokens(&a, &mut _s);
::quote::__private::push_comma(&mut _s);
::quote::ToTokens::to_tokens(&b, &mut _s);
::quote::__private::push_gt(&mut _s);
_s
}quote!(::ct_regex::internal::anchor::AnchorPair<#a, #b>),
64 [a, b, c] => {
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, "anchor");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "AnchorSet");
::quote::__private::push_lt(&mut _s);
::quote::ToTokens::to_tokens(&a, &mut _s);
::quote::__private::push_comma(&mut _s);
::quote::ToTokens::to_tokens(&b, &mut _s);
::quote::__private::push_comma(&mut _s);
::quote::ToTokens::to_tokens(&c, &mut _s);
::quote::__private::push_gt(&mut _s);
_s
}quote!(::ct_regex::internal::anchor::AnchorSet<#a, #b, #c>),
65 _ => {
::core::panicking::panic_fmt(format_args!("an excessive number for anchor assertions were found"));
}panic!("an excessive number for anchor assertions were found"),
66 }
67 }
68
69 pub fn remove_redundant_lookarounds(hir: Hir) -> Hir {
70 match hir.kind() {
71 HirKind::Look(Look::Start) => Hir::empty(),
72 HirKind::Concat(sub) => match &sub[..] {
73 [first, other] if first.kind() == &HirKind::Look(Look::Start) => {
74 other.clone()
75 },
76 [first, remainder @ ..] if first.kind() == &HirKind::Look(Look::Start) => {
77 Hir::concat(remainder.to_vec())
78 },
79 _ => hir,
80 },
81 HirKind::Capture(cap) => Hir::capture(Capture {
82 index: cap.index,
83 name: cap.name.clone(),
84 sub: Box::new(Self::remove_redundant_lookarounds((*cap.sub).clone())),
85 }),
86 _ => hir,
87 }
88 }
89}