Skip to content

Add configurable rules_mod attribute for generated module name#26

Merged
tomtau merged 4 commits intomasterfrom
copilot/make-rules-configurable
Feb 5, 2026
Merged

Add configurable rules_mod attribute for generated module name#26
tomtau merged 4 commits intomasterfrom
copilot/make-rules-configurable

Conversation

Copy link
Contributor

Copilot AI commented Dec 25, 2025

  • Add rules_mod field to Config struct in generator/src/typed/config.rs
  • Update attr.rs to parse #[rules_mod = "..."] attribute
  • Update output.rs to use configurable module name from config
  • Thread config through types_mod() calls (in output.rs and getter.rs)
  • Add rules_mod to proc_macro_derive attributes in derive/src/lib.rs
  • Add tests for the new configuration option
  • Run code review
  • Run CodeQL security check
  • Fix cargo fmt formatting
  • Bump CI toolchain to 1.83
  • Add validation for rules_mod attribute (empty string and valid identifier checks)
Original prompt

Right now, it goes into a hardcoded rules, but it could be made configurable if one wanted to have it defined in the same module.


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 25, 2025

Important

Review skipped

Bot user detected.

To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.


Comment @coderabbitai help to get the list of available commands and usage tips.

Co-authored-by: tomtau <2410580+tomtau@users.noreply.github.com>
@tomtau tomtau requested a review from Copilot December 25, 2025 17:27
Copilot AI changed the title [WIP] Make rules configurable in the module Add configurable rules_mod attribute for generated module name Dec 25, 2025
Copilot AI requested a review from tomtau December 25, 2025 17:29
@tomtau
Copy link
Contributor

tomtau commented Dec 25, 2025

@copilot cargo fmt check fails, can you fix it?

Co-authored-by: tomtau <2410580+tomtau@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Dec 25, 2025

@copilot cargo fmt check fails, can you fix it?

Fixed in 620e4e7. The Output::new() function parameters needed to be split across multiple lines.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a configurable rules module name feature, allowing users to customize the generated module name instead of using the hardcoded "rules" default. The implementation adds a rules_mod attribute that can be set via #[rules_mod = "custom_name"].

  • Added rules_mod: Option<String> field to the Config struct
  • Implemented attribute parsing for #[rules_mod = "..."]
  • Modified code generation to use the configurable module name
  • Refactored Config to be passed by reference throughout the codebase

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
generator/src/typed/config.rs Added rules_mod field to Config struct; removed Copy trait due to String field
generator/src/typed/attr.rs Added parsing logic for the rules_mod attribute
generator/src/typed/output.rs Made types_mod() function accept optional module name parameter; threaded rules_mod through Output struct
generator/src/typed/getter.rs Removed unused types_mod import after refactoring
generator/src/typed/generator.rs Changed all Config parameters from pass-by-value to pass-by-reference to accommodate non-Copy Config
derive/src/lib.rs Added rules_mod to the list of derive macro attributes
derive/tests/custom_rules_mod.rs Added tests for custom module name and default behavior

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

} else if path.is_ident("box_all_rules") {
config.box_rules_only_if_needed = get_bool(attr, "box_all_rules");
} else if path.is_ident("rules_mod") {
config.rules_mod = Some(get_string(attr, "rules_mod"));
Copy link

Copilot AI Dec 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The rules_mod attribute value is not validated before being used with format_ident!. If a user provides an invalid Rust identifier (e.g., containing spaces, starting with a digit, or using keywords like "self" or "super"), it will cause a panic at compile time with an unhelpful error. Consider validating the input is a valid Rust identifier before storing it in the config, or providing a more helpful error message.

Suggested change
config.rules_mod = Some(get_string(attr, "rules_mod"));
let value = get_string(attr, "rules_mod");
if syn::parse_str::<syn::Ident>(&value).is_err() {
panic!(
"Invalid #[rules_mod = \"{}\"]: value must be a valid Rust identifier",
value
);
}
config.rules_mod = Some(value);

Copilot uses AI. Check for mistakes.
no_warnings,
box_rules_only_if_needed,
no_getter,
rules_mod,
Copy link

Copilot AI Dec 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new rules_mod attribute is not documented in the module-level documentation, while other attributes like grammar, grammar_inline, and configuration options are demonstrated in examples. Consider adding documentation or an example showing how to use the rules_mod attribute to customize the generated module name.

Copilot uses AI. Check for mistakes.
Comment on lines +1 to +41
#![allow(unused_variables)]
use anyhow::Result;
use pest3_core::typed::TypedNode as _;
use pest3_derive::Parser;

/// Test that the `rules_mod` attribute allows customizing the generated module name.
mod custom_mod_test {
use super::*;

#[derive(Parser)]
#[grammar_inline = r#"
main = "hello"
"#]
#[rules_mod = "custom"]
struct ParserWithCustomMod;

#[test]
fn custom_module_name() -> Result<()> {
// Access through the custom module name
custom::main::try_parse("hello")?;
Ok(())
}
}

/// Test default behavior (rules module name should be "rules")
mod default_mod_test {
use super::*;

#[derive(Parser)]
#[grammar_inline = r#"
greeting = "world"
"#]
struct ParserWithDefaultMod;

#[test]
fn default_module_name() -> Result<()> {
// Access through the default "rules" module name
rules::greeting::try_parse("world")?;
Ok(())
}
}
Copy link

Copilot AI Dec 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding test coverage for edge cases such as identifiers with underscores (e.g., my_rules), raw identifiers (e.g., r#type), or names that conflict with common Rust keywords. This would help ensure the feature handles various valid Rust identifier patterns correctly.

Copilot uses AI. Check for mistakes.
} else if path.is_ident("box_all_rules") {
config.box_rules_only_if_needed = get_bool(attr, "box_all_rules");
} else if path.is_ident("rules_mod") {
config.rules_mod = Some(get_string(attr, "rules_mod"));
Copy link

Copilot AI Dec 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If an empty string is provided for rules_mod (e.g., #[rules_mod = ""]), it will be stored as Some("") and later passed to format_ident!("{}", "") in the types_mod function, which will cause a panic. Consider validating that the string is not empty and is a valid Rust identifier when parsing the attribute, providing a clear error message to the user.

Suggested change
config.rules_mod = Some(get_string(attr, "rules_mod"));
let rules_mod_value = get_string(attr, "rules_mod");
if rules_mod_value.is_empty() {
panic!(
"Attribute #[rules_mod = \"...\"] must not be empty; provide a valid Rust identifier."
);
}
if syn::parse_str::<proc_macro2::Ident>(&rules_mod_value).is_err() {
panic!(
"Invalid #[rules_mod = \"{}\"] attribute: expected a valid Rust identifier.",
rules_mod_value
);
}
config.rules_mod = Some(rules_mod_value);

Copilot uses AI. Check for mistakes.
@tomtau
Copy link
Contributor

tomtau commented Dec 25, 2025

@copilot Can you bump the toolchain on CI to 1.83, so that cargo clippy can run?

Co-authored-by: tomtau <2410580+tomtau@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Dec 25, 2025

@copilot Can you bump the toolchain on CI to 1.83, so that cargo clippy can run?

Bumped toolchain to 1.83 in d709ff8. Also added input validation for rules_mod to check for empty strings and valid Rust identifiers.

@codecov-commenter
Copy link

codecov-commenter commented Dec 25, 2025

Codecov Report

❌ Patch coverage is 79.41176% with 7 lines in your changes missing coverage. Please review.
✅ Project coverage is 86.97%. Comparing base (2d4260a) to head (d709ff8).

Files with missing lines Patch % Lines
generator/src/typed/attr.rs 50.00% 7 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master      #26      +/-   ##
==========================================
- Coverage   87.04%   86.97%   -0.08%     
==========================================
  Files          26       26              
  Lines        6208     6227      +19     
==========================================
+ Hits         5404     5416      +12     
- Misses        804      811       +7     
Flag Coverage Δ
unittests 86.97% <79.41%> (-0.08%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@tomtau tomtau marked this pull request as ready for review February 5, 2026 08:15
@tomtau tomtau merged commit b80a7df into master Feb 5, 2026
2 checks passed
@tomtau tomtau deleted the copilot/make-rules-configurable branch February 5, 2026 08:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants