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