pest icon indicating copy to clipboard operation
pest copied to clipboard

Provide a way to add `#[attributes]` and custom derive to the generated `Rule` enum

Open dlight opened this issue 4 years ago • 2 comments

pest_derive currently generates a Rule enum without a corresponding enum Rule anywhere in the code. That way, there is no natural place for inserting attributes and custom derive.

My suggestion is that instead of

#[derive(Parser)]
#[grammar = "grammar.pest"]
pub struct MyParser;

The code should be like this:

#[derive(Parser)]
#[grammar = "grammar.pest"]
pub enum Rule;

And then, pest would provide a type GenParser<T>, that stands for generated parser (note: maybe think about a better name), such that GenParser<Rule> would be used exactly like MyParser is currently.

I believe this would require minimal changes in the generated code: instead of impl Parser<Rule> for MyParser { .. } it would generate impl Parser<Rule> for GenParser<Rule> { ... }.

As an added bonus, the code wouldn't have a hidden Rule with no definition or import in the source code, improving discoverability: Rule is written in the code itself and GenParser needs to be imported.

dlight avatar Nov 26 '21 06:11 dlight

Actually, no, that wouldn't work.. custom derive can't change the defined enum. It would need to be something like this

#[derive_parser(grammar = "grammar.pest")]
pub enum Rule;

dlight avatar Nov 26 '21 07:11 dlight

Well, an alternate design is to add both Rule and MyParser to the source code, and add an attribute to make MyParse refer to Rule or vice-versa. Something like this:

#[derive(Parser)]
#[grammar = "grammar.pest"]
pub struct MyParser;

#[pest_rule(parser = "MyParser")]
pub enum Rule;

Or like this

#[pest_rule(grammar = "grammar.pest")]
pub enum Rule;

#[derive(Parser)]
#[pest_rule(rule = "Rule")]
pub struct MyParser;

With it, one could attach custom attributes to both MyParser and Rule.

dlight avatar Nov 26 '21 07:11 dlight