Skip to main content

ct_regex_internal/codegen/convert_hir/
item.rs

1use quote::{ToTokens, format_ident};
2use regex_syntax::hir::{Class, ClassBytes, ClassBytesRange, ClassUnicode, ClassUnicodeRange};
3use syn::Ident;
4
5use crate::haystack::HaystackItem;
6
7pub(crate) trait CodegenItem: HaystackItem + ToTokens {
8    type HirClass: ClassIter<Self>;
9    fn normalize_class(value: Class) -> Self::HirClass;
10    fn ident_fragment() -> Ident;
11}
12
13impl CodegenItem for u8 {
14    type HirClass = ClassBytes;
15
16    fn normalize_class(value: Class) -> Self::HirClass {
17        match value {
18            Class::Unicode(unicode) => {
19                unicode.to_byte_class().expect("failed to convert to byte class")
20            },
21            Class::Bytes(bytes) => bytes,
22        }
23    }
24
25    fn ident_fragment() -> Ident {
26        ::quote::__private::mk_ident(&::alloc::__export::must_use({
                ::alloc::fmt::format(format_args!("Byte"))
            }), ::quote::__private::Option::None)format_ident!("Byte")
27    }
28}
29
30impl CodegenItem for char {
31    type HirClass = ClassUnicode;
32
33    fn normalize_class(value: Class) -> Self::HirClass {
34        match value {
35            Class::Unicode(unicode) => unicode,
36            Class::Bytes(bytes) => {
37                bytes.to_unicode_class().expect("failed to convert to unicode class")
38            },
39        }
40    }
41
42    fn ident_fragment() -> Ident {
43        ::quote::__private::mk_ident(&::alloc::__export::must_use({
                ::alloc::fmt::format(format_args!("Scalar"))
            }), ::quote::__private::Option::None)format_ident!("Scalar")
44    }
45}
46
47pub(crate) trait ClassIter<I: CodegenItem> {
48    type Range: ClassRange<I>;
49
50    fn ranges(&self) -> impl Iterator<Item = &Self::Range>;
51}
52
53impl ClassIter<char> for ClassUnicode {
54    type Range = ClassUnicodeRange;
55
56    fn ranges(&self) -> impl Iterator<Item = &Self::Range> {
57        self.ranges().iter()
58    }
59}
60
61impl ClassIter<u8> for ClassBytes {
62    type Range = ClassBytesRange;
63
64    fn ranges(&self) -> impl Iterator<Item = &Self::Range> {
65        self.ranges().iter()
66    }
67}
68
69pub(crate) trait ClassRange<I: CodegenItem> {
70    fn start(&self) -> I;
71    fn end(&self) -> I;
72}
73
74impl ClassRange<char> for ClassUnicodeRange {
75    fn start(&self) -> char {
76        self.start()
77    }
78
79    fn end(&self) -> char {
80        self.end()
81    }
82}
83
84impl ClassRange<u8> for ClassBytesRange {
85    fn start(&self) -> u8 {
86        self.start()
87    }
88
89    fn end(&self) -> u8 {
90        self.end()
91    }
92}