Skip to main content

ct_regex_internal/codegen/convert_hir/
metadata.rs

1use std::collections::HashMap;
2use std::mem;
3
4use quote::format_ident;
5use syn::Ident;
6
7use crate::codegen::{CodegenItem};
8use crate::matcher::ClassEntry;
9
10#[derive(#[automatically_derived]
impl ::core::fmt::Debug for Group {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field2_finish(f, "Group", "name",
            &self.name, "required", &&self.required)
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for Group {
    #[inline]
    fn clone(&self) -> Group {
        Group {
            name: ::core::clone::Clone::clone(&self.name),
            required: ::core::clone::Clone::clone(&self.required),
        }
    }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for Group {
    #[inline]
    fn eq(&self, other: &Group) -> bool {
        self.required == other.required && self.name == other.name
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for Group {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<Option<Box<str>>>;
        let _: ::core::cmp::AssertParamIsEq<bool>;
    }
}Eq)]
11pub(crate) struct Group {
12    pub name: Option<Box<str>>,
13    pub required: bool,
14}
15
16#[derive(#[automatically_derived]
impl<I: ::core::fmt::Debug + CodegenItem> ::core::fmt::Debug for
    ExprMetadata<I> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field5_finish(f, "ExprMetadata",
            "name", &self.name, "groups", &self.groups, "required",
            &self.required, "literals", &self.literals, "classes",
            &&self.classes)
    }
}Debug, #[automatically_derived]
impl<I: ::core::clone::Clone + CodegenItem> ::core::clone::Clone for
    ExprMetadata<I> {
    #[inline]
    fn clone(&self) -> ExprMetadata<I> {
        ExprMetadata {
            name: ::core::clone::Clone::clone(&self.name),
            groups: ::core::clone::Clone::clone(&self.groups),
            required: ::core::clone::Clone::clone(&self.required),
            literals: ::core::clone::Clone::clone(&self.literals),
            classes: ::core::clone::Clone::clone(&self.classes),
        }
    }
}Clone)]
17pub(crate) struct ExprMetadata<I: CodegenItem> {
18    pub name: Ident,
19    // Group ids are provided by regex_syntax as a u32, and not returned in the right order, so we
20    // store them in a map before checking them and creating a Vec later.
21    pub groups: HashMap<u32, Group>,
22    pub required: bool,
23    pub literals: Vec<Box<[u8]>>,
24    // TODO: avoid duplicates
25    pub classes: Vec<Box<[ClassEntry<I>]>>,
26}
27
28impl<I: CodegenItem> ExprMetadata<I> {
29    pub fn new(name: Ident) -> ExprMetadata<I> {
30        let mut groups = HashMap::new();
31        groups.insert(0, Group {
32            name: Some("whole_match".into()),
33            required: true,
34        });
35        ExprMetadata {
36            name,
37            groups,
38            required: true,
39            literals: Vec::new(),
40            classes: Vec::new(),
41        }
42    }
43
44    pub fn insert_group(&mut self, index: u32, name: Option<Box<str>>) {
45        self.groups.insert(index, Group {
46            name,
47            required: self.required,
48        });
49    }
50
51    pub fn take_groups(&mut self) -> Vec<Group> {
52        let mut items: Vec<_> = mem::take(&mut self.groups).into_iter().collect();
53        items.sort_by_key(|(i, _)| *i);
54
55        if items
56            .iter()
57            .enumerate()
58            .any(|(num, (index, _))| num != *index as usize)
59        {
60            { ::core::panicking::panic_fmt(format_args!("missing a capture group")); };panic!("missing a capture group");
61        }
62
63        items.into_iter().map(|(_, item)| item).collect()
64    }
65
66    pub fn insert_literal(&mut self, literal: Box<[u8]>) -> Ident {
67        let index = self.literals.len();
68        self.literals.push(literal);
69        create_literal_id(&self.name, index)
70    }
71
72    pub fn insert_class(&mut self, mut entry: Box<[ClassEntry<I>]>) -> Ident {
73        let index = self.classes.len();
74        entry.sort();
75        self.classes.push(entry);
76        create_class_id::<I>(&self.name, index)
77    }
78}
79
80impl<I: CodegenItem, J: CodegenItem> PartialEq<ExprMetadata<J>> for ExprMetadata<I> {
81    fn eq(&self, other: &ExprMetadata<J>) -> bool {
82        self.name == other.name
83            && self.groups == other.groups
84            && self.literals == other.literals
85    }
86}
87
88pub(crate) fn create_literal_id(name: &Ident, num: usize) -> Ident {
89    match ::quote::__private::IdentFragmentAdapter(&name) {
    arg =>
        match ::quote::__private::IdentFragmentAdapter(&num) {
            arg =>
                ::quote::__private::mk_ident(&::alloc::__export::must_use({
                                ::alloc::fmt::format(format_args!("{0}Literal{1}", arg,
                                        arg))
                            }),
                    ::quote::__private::Option::None.or(arg.span()).or(arg.span())),
        },
}format_ident!("{}Literal{}", name, num)
90}
91
92pub(crate) fn create_class_id<I: CodegenItem>(name: &Ident, num: usize) -> Ident {
93    match ::quote::__private::IdentFragmentAdapter(&name) {
    arg =>
        match ::quote::__private::IdentFragmentAdapter(&I::ident_fragment()) {
            arg =>
                match ::quote::__private::IdentFragmentAdapter(&num) {
                    arg =>
                        ::quote::__private::mk_ident(&::alloc::__export::must_use({
                                        ::alloc::fmt::format(format_args!("{0}{1}Class{2}", arg,
                                                arg, arg))
                                    }),
                            ::quote::__private::Option::None.or(arg.span()).or(arg.span()).or(arg.span())),
                },
        },
}format_ident!("{}{}Class{}", name, I::ident_fragment(), num)
94}