ere_macros/
lib.rs

1use ere_core;
2use proc_macro::TokenStream;
3
4extern crate proc_macro;
5
6/// This is the primary entrypoint to the `ere` crate.
7/// Checks and compiles a regular expression into a [`Regex<N>`](`ere_core::Regex<N>`).
8///
9/// This compilation happens during build using proc macros,
10/// resulting in rust code equivalent to your regex.
11/// This code can then by further optimized by rustc when compiled directly into the binary.
12///
13/// The generic `const N: usize` will be the number of capture groups present in the regular expression
14/// (including capture group 0 which is the entire matched text).
15/// You will need to properly specify this in the generics for the regex (default if unspecified is 1).
16/// When using [`Regex<N>::exec`](`ere_core::Regex<N>::exec`), this is the length of the captures returned.
17///
18/// ```
19/// use ere_core::Regex; // usually `ere::Regex`
20/// use ere_macros::compile_regex; // usually `ere::compile_regex`
21///
22/// const MY_REGEX: Regex<2> = compile_regex!("a(b?)c");
23/// ```
24#[proc_macro]
25pub fn compile_regex(stream: TokenStream) -> TokenStream {
26    return ere_core::__compile_regex(stream);
27}
28
29/// Checks and compiles a regular expression into a [`ere_core::pike_vm::PikeVM<N>`].
30/// Unless you specifically want this engine, you might want to use [`compile_regex!`] instead.
31///
32/// This compilation happens during build using proc macros,
33/// resulting in rust code equivalent to your regex.
34/// This code can then by further optimized by rustc when compiled directly into the binary.
35///
36/// The generic `const N: usize` will be the number of capture groups present in the regular expression
37/// (including capture group 0 which is the entire matched text).
38/// You will need to properly specify this in the generics for the regex (default if unspecified is 1).
39/// When using [`PikeVM<N>::exec`](`ere_core::pike_vm::PikeVM<N>::exec`), this is the length of the captures returned.
40///
41/// ```
42/// use ere_core::pike_vm::PikeVM;
43/// use ere_macros::compile_regex_pikevm;
44///
45/// const MY_REGEX: PikeVM<2> = compile_regex_pikevm!("a(b?)c");
46/// ```
47#[proc_macro]
48pub fn compile_regex_pikevm(stream: TokenStream) -> TokenStream {
49    return ere_core::__compile_regex_engine_pike_vm(stream);
50}
51
52/// Checks and compiles a regular expression into a [`ere_core::pike_vm_u8::U8PikeVM<N>`].
53/// Unless you specifically want this engine, you might want to use [`compile_regex!`] instead.
54///
55/// This compilation happens during build using proc macros,
56/// resulting in rust code equivalent to your regex.
57/// This code can then by further optimized by rustc when compiled directly into the binary.
58///
59/// The generic `const N: usize` will be the number of capture groups present in the regular expression
60/// (including capture group 0 which is the entire matched text).
61/// You will need to properly specify this in the generics for the regex (default if unspecified is 1).
62/// When using [`U8PikeVM<N>::exec`](`ere_core::pike_vm_u8::U8PikeVM<N>::exec`), this is the length of the captures returned.
63///
64/// ```
65/// use ere_core::pike_vm_u8::U8PikeVM;
66/// use ere_macros::compile_regex_u8pikevm;
67///
68/// const MY_REGEX: U8PikeVM<2> = compile_regex_u8pikevm!("a(b?)c");
69/// ```
70#[proc_macro]
71pub fn compile_regex_u8pikevm(stream: TokenStream) -> TokenStream {
72    return ere_core::__compile_regex_engine_pike_vm_u8(stream);
73}
74
75/// Checks and compiles a regular expression into a [`ere_core::one_pass_u8::U8OnePass<N>`].
76/// Unless you specifically want this engine, you might want to use [`compile_regex!`] instead.
77///
78/// This compilation happens during build using proc macros,
79/// resulting in rust code equivalent to your regex.
80/// This code can then by further optimized by rustc when compiled directly into the binary.
81///
82/// The generic `const N: usize` will be the number of capture groups present in the regular expression
83/// (including capture group 0 which is the entire matched text).
84/// You will need to properly specify this in the generics for the regex (default if unspecified is 1).
85/// When using [`U8OnePass<N>::exec`](`ere_core::one_pass_u8::U8OnePass<N>::exec`), this is the length of the captures returned.
86///
87/// ```
88/// use ere_core::one_pass_u8::U8OnePass;
89/// use ere_macros::compile_regex_u8onepass;
90///
91/// const MY_REGEX: U8OnePass<2> = compile_regex_u8onepass!("^a(b?)c$");
92/// ```
93///
94/// ---
95///
96/// Note that this engine does not support all valid regular expressions,
97/// and will raise a compile error if necessary.
98/// For example, unanchored regexes are generally not one-pass.
99///
100#[proc_macro]
101pub fn compile_regex_u8onepass(stream: TokenStream) -> TokenStream {
102    return ere_core::__compile_regex_engine_one_pass_u8(stream);
103}
104
105/// EXPERIMENTAL: this attribute provides an alternate syntax with finer control for creating regexes.
106///
107/// Compared with [`compile_regex!`], this allows the type system to know which capture groups
108/// should be optional and which should not.
109///
110/// For example:
111///
112/// ```
113/// use ere_macros::regex;
114///
115/// #[derive(Debug, PartialEq, Eq)]
116/// #[regex(r"^#?([[:xdigit:]]{2})([[:xdigit:]]{2})([[:xdigit:]]{2})([[:xdigit:]]{2})?$")]
117/// pub struct HexColor<'a>(
118///     pub &'a str,
119///     pub &'a str,
120///     pub &'a str,
121///     pub &'a str,
122///     pub Option<&'a str>,
123/// );
124///
125/// assert!(HexColor::test("#1F1F1F"));
126/// assert!(HexColor::test("#1F1F1F80"));
127/// assert!(HexColor::test("20202020"));
128///
129/// assert_eq!(
130///     HexColor::exec("#112233"),
131///     Some(HexColor(
132///         "#112233",
133///         "11",
134///         "22",
135///         "33",
136///         None,
137///     )),
138/// );
139/// assert_eq!(
140///     HexColor::exec("#11223344"),
141///     Some(HexColor(
142///         "#11223344",
143///         "11",
144///         "22",
145///         "33",
146///         Some("44"),
147///     )),
148/// );
149/// ```
150///
151/// ---
152///
153/// Note that it is required to specify the fields with the proper type
154/// (i.e. `&'a str` or `Option<&'a str>` depending on the capture group)
155/// and the lifetime should be the first generic argument on the struct.
156///
157/// The field for the 0th capture group should never be an `Option` since if there is a match,
158/// it will always contain the entire match (and otherwise `exec` returns `None`).
159#[cfg(feature = "unstable-attr-regex")]
160#[proc_macro_attribute]
161pub fn regex(attr: TokenStream, input: TokenStream) -> TokenStream {
162    return ere_core::__compile_regex_attr(attr, input);
163}