-
Notifications
You must be signed in to change notification settings - Fork 34
Add new lint to enforce snake-case usage with new api_dto macro #247
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
Note Other AI code review bot(s) detectedCodeRabbit 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. 📝 Walkthrough🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
Comment |
Signed-off-by: nanoandrew4 <andressmithdev@pm.me>
b3d16ce to
84540b5
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/Cargo.toml`:
- Around line 21-84: Add the missing example entry for the UI test file by
creating an example target named "fail_pascal_case" that points to
"ui/fail_pascal_case.rs" so every file in the ui/ directory has a corresponding
[[example]] entry; update the Cargo.toml examples list to include this new
[[example]] with name fail_pascal_case and path ui/fail_pascal_case.rs.
🧹 Nitpick comments (3)
dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/README.md (1)
1-9: Well-documented lint rule.The README clearly explains what the lint does, why it matters, and provides helpful examples.
Minor markdown nit: Consider using
##(h2) instead of###(h3) for section headings to follow proper heading hierarchy after the h1 title.📝 Optional heading level fix
# de0803_api_snake_case -### What it does +## What it does Checks that DTOs (structs and enums) defined in the `api/rest` directory use `snake_case` for serde renaming configurations. Specifically: 1. `#[serde(rename_all = "...")]` on structs/enums must be "snake_case". 2. `#[serde(rename = "...")]` on fields must be in snake_case. -### Why is this bad? +## Why is this bad? The API standard requires all JSON properties to be in `snake_case`. Using other casing styles (like `camelCase`, `PascalCase`, etc.) leads to inconsistent API responses and violations of the project's API guidelines. -### Example +## Exampledylint_lints/de08_rest_api_conventions/de0803_api_snake_case/Cargo.toml (1)
1-19: Good crate structure following conventions.The crate correctly uses workspace dependencies for
clippy_utils,dylint_linting,lint_utils,dylint_testing, andserdeas per coding guidelines.Consider updating edition to "2024" for consistency.
Other lint crates in this PR (e.g.,
de0110_no_schema_for_on_gts_structs,de0902_no_schema_for_on_gts_structs) useedition = "2024". This crate usesedition = "2021", which creates inconsistency across the workspace.Suggested fix
[package] name = "de0803_api_snake_case" version = "0.1.0" authors = ["Hypernetix"] description = "DTOs must not use CamelCase or PascalCase in serde rename_all, only snake_case is allowed" -edition = "2021" +edition = "2024" publish = falsedylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_pascal_case.rs (1)
5-6: Minor: Comment description doesn't match the violation type.The comment says "DTO fields must not use non-snake_case" but this test validates a type-level
rename_allattribute, not a field-levelrename. Consider updating to:-// Should trigger DE0803 - DTO fields must not use non-snake_case in serde rename/rename_all +// Should trigger DE0803 - DTOs must not use non-snake_case in serde rename_allThis would more accurately describe the specific violation being tested and align with the actual lint message.
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
dylint_lints/Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (45)
dylint_lints/Cargo.tomldylint_lints/de01_contract_layer/de0101_no_serde_in_contract/Cargo.tomldylint_lints/de01_contract_layer/de0110_no_schema_for_on_gts_structs/Cargo.tomldylint_lints/de02_api_layer/de0203_dtos_must_have_serde_derives/Cargo.tomldylint_lints/de02_api_layer/de0204_dtos_must_have_toschema_derive/Cargo.tomldylint_lints/de08_rest_api_conventions/de0803_api_snake_case/Cargo.tomldylint_lints/de08_rest_api_conventions/de0803_api_snake_case/README.mddylint_lints/de08_rest_api_conventions/de0803_api_snake_case/rust-toolchaindylint_lints/de08_rest_api_conventions/de0803_api_snake_case/src/lib.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_camel_case.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_camel_case.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_camel_case.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_camel_case.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_kebab_case.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_kebab_case.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_pascal_case.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_pascal_case.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_screaming_kebab_case.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_screaming_kebab_case.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_screaming_snake_case.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_screaming_snake_case.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_uppercase.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_uppercase.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_kebab_case.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_kebab_case.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_lowercase.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_lowercase.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_pascal_case.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_pascal_case.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_screaming_kebab_case.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_screaming_kebab_case.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_screaming_snake_case.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_screaming_snake_case.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_uppercase.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_uppercase.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/pass.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/pass.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/pass_field_lowercase.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/pass_field_lowercase.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/pass_field_snake_case.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/pass_field_snake_case.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/pass_outside_api.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/pass_outside_api.stderrdylint_lints/de09_gts_layer/de0901_gts_string_pattern/Cargo.tomldylint_lints/de09_gts_layer/de0902_no_schema_for_on_gts_structs/Cargo.toml
🧰 Additional context used
📓 Path-based instructions (2)
dylint_lints/**/Cargo.toml
📄 CodeRabbit inference engine (dylint_lints/AGENTS.md)
dylint_lints/**/Cargo.toml: InCargo.tomlfor lint crates, reference common workspace dependencies (clippy_utils,dylint_linting,lint_utils) using.workspace = trueto avoid duplication
Define example targets in lint crateCargo.tomlwith[[example]]sections for each UI test case
Register new lint crates by adding them to thememberslist in the workspace rootCargo.toml
Files:
dylint_lints/de01_contract_layer/de0101_no_serde_in_contract/Cargo.tomldylint_lints/de09_gts_layer/de0901_gts_string_pattern/Cargo.tomldylint_lints/de02_api_layer/de0203_dtos_must_have_serde_derives/Cargo.tomldylint_lints/de01_contract_layer/de0110_no_schema_for_on_gts_structs/Cargo.tomldylint_lints/de09_gts_layer/de0902_no_schema_for_on_gts_structs/Cargo.tomldylint_lints/de08_rest_api_conventions/de0803_api_snake_case/Cargo.tomldylint_lints/Cargo.tomldylint_lints/de02_api_layer/de0204_dtos_must_have_toschema_derive/Cargo.toml
dylint_lints/**/src/lib.rs
📄 CodeRabbit inference engine (dylint_lints/AGENTS.md)
dylint_lints/**/src/lib.rs: Usedeclare_pre_expansion_lint!for lints that check derive attributes before macro expansion (e.g., detecting serde/utoipa derives)
UseEarlyLintPasswithrustc_astfor pre-expansion lints that need to see#[derive(...)]attributes directly before macro expansion
Usedeclare_early_lint!for checking syntax and structure after macro expansion but before type resolution without type information
Usedeclare_late_lint!withLateLintPassandrustc_hirwhen type information or semantic analysis is required
Useui_test_exampleswhen tests need external dependencies (serde, utoipa) or have logically distinct scenarios with explicit test organization
Useui_testwhen all tests have no external dependencies and you have many small, similar test cases for simpler configuration
Every lint crate MUST include atest_comment_annotations_match_stderrtest usinglint_utils::test_comment_annotations_match_stderrto validate comment/stderr alignment
Useis_in_contract_module_ast()helper fromlint_utilscrate to check if an AST item is in a contract/ directory
Document lint behavior in doc comments within the lint implementation
Select pre-expansion lint pass for detecting serde/utoipa derives that must be checked before proc macros expand
Files:
dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/src/lib.rs
🧠 Learnings (22)
📚 Learning: 2026-01-14T17:18:31.902Z
Learnt from: CR
Repo: hypernetix/hyperspot PR: 0
File: dylint_lints/AGENTS.md:0-0
Timestamp: 2026-01-14T17:18:31.902Z
Learning: Applies to dylint_lints/ui/*.rs : Include at least one test case with no violations (empty or near-empty `.stderr` file) in UI tests
Applied to files:
dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_pascal_case.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_screaming_kebab_case.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_camel_case.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_pascal_case.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_uppercase.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_screaming_kebab_case.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_lowercase.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_camel_case.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_uppercase.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_pascal_case.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_kebab_case.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_lowercase.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_kebab_case.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_uppercase.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_kebab_case.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_screaming_snake_case.rs
📚 Learning: 2026-01-14T17:18:31.902Z
Learnt from: CR
Repo: hypernetix/hyperspot PR: 0
File: dylint_lints/AGENTS.md:0-0
Timestamp: 2026-01-14T17:18:31.902Z
Learning: Applies to dylint_lints/**/src/lib.rs : Every lint crate MUST include a `test_comment_annotations_match_stderr` test using `lint_utils::test_comment_annotations_match_stderr` to validate comment/stderr alignment
Applied to files:
dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_pascal_case.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_screaming_kebab_case.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_uppercase.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_lowercase.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_uppercase.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/src/lib.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_pascal_case.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_lowercase.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_kebab_case.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_screaming_snake_case.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_kebab_case.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_camel_case.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_screaming_snake_case.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_screaming_snake_case.rs
📚 Learning: 2026-01-14T17:18:31.902Z
Learnt from: CR
Repo: hypernetix/hyperspot PR: 0
File: dylint_lints/AGENTS.md:0-0
Timestamp: 2026-01-14T17:18:31.902Z
Learning: Applies to dylint_lints/**/src/lib.rs : Select pre-expansion lint pass for detecting serde/utoipa derives that must be checked before proc macros expand
Applied to files:
dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_kebab_case.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/pass.rsdylint_lints/de01_contract_layer/de0101_no_serde_in_contract/Cargo.tomldylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_camel_case.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_screaming_kebab_case.rsdylint_lints/de09_gts_layer/de0901_gts_string_pattern/Cargo.tomldylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_pascal_case.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_pascal_case.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_uppercase.rsdylint_lints/de02_api_layer/de0203_dtos_must_have_serde_derives/Cargo.tomldylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_uppercase.stderrdylint_lints/de01_contract_layer/de0110_no_schema_for_on_gts_structs/Cargo.tomldylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_screaming_kebab_case.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_lowercase.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_camel_case.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/pass_outside_api.rsdylint_lints/de09_gts_layer/de0902_no_schema_for_on_gts_structs/Cargo.tomldylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_uppercase.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/pass_field_lowercase.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_camel_case.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/src/lib.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_pascal_case.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_kebab_case.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/Cargo.tomldylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_lowercase.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_kebab_case.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_uppercase.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_screaming_kebab_case.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_screaming_snake_case.stderrdylint_lints/Cargo.tomldylint_lints/de02_api_layer/de0204_dtos_must_have_toschema_derive/Cargo.tomldylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_camel_case.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/pass_field_snake_case.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_screaming_snake_case.rs
📚 Learning: 2026-01-14T17:18:31.902Z
Learnt from: CR
Repo: hypernetix/hyperspot PR: 0
File: dylint_lints/AGENTS.md:0-0
Timestamp: 2026-01-14T17:18:31.902Z
Learning: Applies to dylint_lints/ui/*.rs : For struct/enum/function multiline spans in UI tests, place error comments on the first line of the item declaration (e.g., `pub struct Name`), not on the `#[derive(...)]` attribute line
Applied to files:
dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_kebab_case.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_screaming_kebab_case.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_camel_case.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_screaming_kebab_case.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_pascal_case.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_pascal_case.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_uppercase.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_uppercase.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_screaming_kebab_case.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_lowercase.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_camel_case.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/pass_outside_api.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_uppercase.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/pass_field_lowercase.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_camel_case.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/src/lib.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_pascal_case.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_kebab_case.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_lowercase.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_kebab_case.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_screaming_snake_case.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_uppercase.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_screaming_kebab_case.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_screaming_snake_case.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_kebab_case.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_camel_case.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_screaming_snake_case.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_screaming_snake_case.rs
📚 Learning: 2026-01-14T17:18:31.902Z
Learnt from: CR
Repo: hypernetix/hyperspot PR: 0
File: dylint_lints/AGENTS.md:0-0
Timestamp: 2026-01-14T17:18:31.902Z
Learning: Organize Rust lint crates with structure: `src/lib.rs` for implementation, `ui/` directory for UI test files with corresponding `.stderr` files
Applied to files:
dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_kebab_case.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_screaming_kebab_case.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_camel_case.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_pascal_case.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_uppercase.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_screaming_kebab_case.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_lowercase.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_camel_case.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_pascal_case.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/Cargo.tomldylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_lowercase.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_uppercase.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_screaming_snake_case.rs
📚 Learning: 2026-01-14T17:18:31.902Z
Learnt from: CR
Repo: hypernetix/hyperspot PR: 0
File: dylint_lints/AGENTS.md:0-0
Timestamp: 2026-01-14T17:18:31.902Z
Learning: Applies to dylint_lints/**/src/lib.rs : Use `ui_test_examples` when tests need external dependencies (serde, utoipa) or have logically distinct scenarios with explicit test organization
Applied to files:
dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_kebab_case.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/pass.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_screaming_kebab_case.stderrdylint_lints/de01_contract_layer/de0101_no_serde_in_contract/Cargo.tomldylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_camel_case.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_screaming_kebab_case.rsdylint_lints/de09_gts_layer/de0901_gts_string_pattern/Cargo.tomldylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_pascal_case.rsdylint_lints/de02_api_layer/de0203_dtos_must_have_serde_derives/Cargo.tomldylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_uppercase.stderrdylint_lints/de01_contract_layer/de0110_no_schema_for_on_gts_structs/Cargo.tomldylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_lowercase.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_camel_case.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/pass_outside_api.rsdylint_lints/de09_gts_layer/de0902_no_schema_for_on_gts_structs/Cargo.tomldylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_uppercase.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/src/lib.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_pascal_case.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/Cargo.tomldylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_lowercase.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_kebab_case.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_uppercase.rsdylint_lints/Cargo.tomldylint_lints/de02_api_layer/de0204_dtos_must_have_toschema_derive/Cargo.tomldylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_screaming_snake_case.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_screaming_snake_case.rs
📚 Learning: 2026-01-14T17:18:31.902Z
Learnt from: CR
Repo: hypernetix/hyperspot PR: 0
File: dylint_lints/AGENTS.md:0-0
Timestamp: 2026-01-14T17:18:31.902Z
Learning: Applies to dylint_lints/ui/*.stderr : Generate `.stderr` files by running tests (`cargo test --lib ui_examples`), copying normalized stderr output, and using `$DIR/` placeholder for file paths with exact line number matching
Applied to files:
dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_screaming_kebab_case.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_uppercase.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_lowercase.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_uppercase.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_pascal_case.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_kebab_case.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_screaming_snake_case.rs
📚 Learning: 2026-01-14T17:18:31.902Z
Learnt from: CR
Repo: hypernetix/hyperspot PR: 0
File: dylint_lints/AGENTS.md:0-0
Timestamp: 2026-01-14T17:18:31.902Z
Learning: Applies to dylint_lints/ui/*.rs : Place test comment annotations (`// Should trigger DEXXX - description` or `// Should not trigger DEXXX - description`) on the line immediately before where the error is reported, not on attribute lines
Applied to files:
dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_screaming_kebab_case.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_uppercase.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_lowercase.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_camel_case.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_camel_case.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/src/lib.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_pascal_case.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_kebab_case.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_screaming_kebab_case.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_screaming_snake_case.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_camel_case.stderr
📚 Learning: 2026-01-14T17:18:31.902Z
Learnt from: CR
Repo: hypernetix/hyperspot PR: 0
File: dylint_lints/AGENTS.md:0-0
Timestamp: 2026-01-14T17:18:31.902Z
Learning: Applies to dylint_lints/**/src/lib.rs : Document lint behavior in doc comments within the lint implementation
Applied to files:
dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_screaming_kebab_case.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_camel_case.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_pascal_case.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_pascal_case.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_screaming_kebab_case.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/README.mddylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_camel_case.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/pass_outside_api.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/pass_field_lowercase.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_camel_case.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/src/lib.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_lowercase.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_uppercase.rsdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_screaming_snake_case.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_camel_case.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_screaming_snake_case.rs
📚 Learning: 2026-01-14T17:18:31.902Z
Learnt from: CR
Repo: hypernetix/hyperspot PR: 0
File: dylint_lints/AGENTS.md:0-0
Timestamp: 2026-01-14T17:18:31.902Z
Learning: Applies to dylint_lints/**/Cargo.toml : In `Cargo.toml` for lint crates, reference common workspace dependencies (`clippy_utils`, `dylint_linting`, `lint_utils`) using `.workspace = true` to avoid duplication
Applied to files:
dylint_lints/de01_contract_layer/de0101_no_serde_in_contract/Cargo.tomldylint_lints/de09_gts_layer/de0901_gts_string_pattern/Cargo.tomldylint_lints/de02_api_layer/de0203_dtos_must_have_serde_derives/Cargo.tomldylint_lints/de01_contract_layer/de0110_no_schema_for_on_gts_structs/Cargo.tomldylint_lints/de09_gts_layer/de0902_no_schema_for_on_gts_structs/Cargo.tomldylint_lints/de08_rest_api_conventions/de0803_api_snake_case/Cargo.tomldylint_lints/Cargo.tomldylint_lints/de02_api_layer/de0204_dtos_must_have_toschema_derive/Cargo.toml
📚 Learning: 2026-01-14T17:18:31.902Z
Learnt from: CR
Repo: hypernetix/hyperspot PR: 0
File: dylint_lints/AGENTS.md:0-0
Timestamp: 2026-01-14T17:18:31.902Z
Learning: Applies to dylint_lints/**/Cargo.toml : Register new lint crates by adding them to the `members` list in the workspace root `Cargo.toml`
Applied to files:
dylint_lints/de01_contract_layer/de0101_no_serde_in_contract/Cargo.tomldylint_lints/de09_gts_layer/de0901_gts_string_pattern/Cargo.tomldylint_lints/de02_api_layer/de0203_dtos_must_have_serde_derives/Cargo.tomldylint_lints/de01_contract_layer/de0110_no_schema_for_on_gts_structs/Cargo.tomldylint_lints/de09_gts_layer/de0902_no_schema_for_on_gts_structs/Cargo.tomldylint_lints/de08_rest_api_conventions/de0803_api_snake_case/Cargo.tomldylint_lints/Cargo.tomldylint_lints/de02_api_layer/de0204_dtos_must_have_toschema_derive/Cargo.toml
📚 Learning: 2026-01-14T17:18:31.902Z
Learnt from: CR
Repo: hypernetix/hyperspot PR: 0
File: dylint_lints/AGENTS.md:0-0
Timestamp: 2026-01-14T17:18:31.902Z
Learning: Applies to dylint_lints/**/src/lib.rs : Use `is_in_contract_module_ast()` helper from `lint_utils` crate to check if an AST item is in a contract/ directory
Applied to files:
dylint_lints/de01_contract_layer/de0101_no_serde_in_contract/Cargo.tomldylint_lints/de08_rest_api_conventions/de0803_api_snake_case/src/lib.rs
📚 Learning: 2026-01-14T17:18:31.902Z
Learnt from: CR
Repo: hypernetix/hyperspot PR: 0
File: dylint_lints/AGENTS.md:0-0
Timestamp: 2026-01-14T17:18:31.902Z
Learning: Applies to dylint_lints/**/src/lib.rs : Use `ui_test` when all tests have no external dependencies and you have many small, similar test cases for simpler configuration
Applied to files:
dylint_lints/de01_contract_layer/de0101_no_serde_in_contract/Cargo.tomldylint_lints/de02_api_layer/de0203_dtos_must_have_serde_derives/Cargo.tomldylint_lints/de02_api_layer/de0204_dtos_must_have_toschema_derive/Cargo.toml
📚 Learning: 2026-01-14T17:18:31.902Z
Learnt from: CR
Repo: hypernetix/hyperspot PR: 0
File: dylint_lints/AGENTS.md:0-0
Timestamp: 2026-01-14T17:18:31.902Z
Learning: Use `cargo dylint new <lint_name>` in `dylint_lints/` directory to initialize new lint crates with proper scaffolding
Applied to files:
dylint_lints/de01_contract_layer/de0101_no_serde_in_contract/Cargo.tomldylint_lints/de02_api_layer/de0203_dtos_must_have_serde_derives/Cargo.tomldylint_lints/de08_rest_api_conventions/de0803_api_snake_case/Cargo.tomldylint_lints/Cargo.toml
📚 Learning: 2026-01-14T17:18:31.902Z
Learnt from: CR
Repo: hypernetix/hyperspot PR: 0
File: dylint_lints/AGENTS.md:0-0
Timestamp: 2026-01-14T17:18:31.902Z
Learning: Applies to dylint_lints/**/src/lib.rs : Use `declare_pre_expansion_lint!` for lints that check derive attributes before macro expansion (e.g., detecting serde/utoipa derives)
Applied to files:
dylint_lints/de01_contract_layer/de0101_no_serde_in_contract/Cargo.tomldylint_lints/de02_api_layer/de0203_dtos_must_have_serde_derives/Cargo.tomldylint_lints/de01_contract_layer/de0110_no_schema_for_on_gts_structs/Cargo.tomldylint_lints/de09_gts_layer/de0902_no_schema_for_on_gts_structs/Cargo.tomldylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_camel_case.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/src/lib.rsdylint_lints/de02_api_layer/de0204_dtos_must_have_toschema_derive/Cargo.toml
📚 Learning: 2026-01-14T17:18:31.902Z
Learnt from: CR
Repo: hypernetix/hyperspot PR: 0
File: dylint_lints/AGENTS.md:0-0
Timestamp: 2026-01-14T17:18:31.902Z
Learning: Applies to dylint_lints/ui/main.rs : If generated `main.rs` and `main.stderr` are empty, remove them from the UI test directory
Applied to files:
dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_uppercase.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_pascal_case.stderr
📚 Learning: 2026-01-14T17:18:31.902Z
Learnt from: CR
Repo: hypernetix/hyperspot PR: 0
File: dylint_lints/AGENTS.md:0-0
Timestamp: 2026-01-14T17:18:31.902Z
Learning: Applies to dylint_lints/**/Cargo.toml : Define example targets in lint crate `Cargo.toml` with `[[example]]` sections for each UI test case
Applied to files:
dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_lowercase.stderrdylint_lints/de08_rest_api_conventions/de0803_api_snake_case/Cargo.toml
📚 Learning: 2026-01-14T17:18:31.902Z
Learnt from: CR
Repo: hypernetix/hyperspot PR: 0
File: dylint_lints/AGENTS.md:0-0
Timestamp: 2026-01-14T17:18:31.902Z
Learning: Applies to dylint_lints/**/src/lib.rs : Use `EarlyLintPass` with `rustc_ast` for pre-expansion lints that need to see `#[derive(...)]` attributes directly before macro expansion
Applied to files:
dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/src/lib.rs
📚 Learning: 2026-01-14T17:18:31.902Z
Learnt from: CR
Repo: hypernetix/hyperspot PR: 0
File: dylint_lints/AGENTS.md:0-0
Timestamp: 2026-01-14T17:18:31.902Z
Learning: Applies to dylint_lints/**/src/lib.rs : Use `declare_early_lint!` for checking syntax and structure after macro expansion but before type resolution without type information
Applied to files:
dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/src/lib.rs
📚 Learning: 2026-01-14T17:18:31.902Z
Learnt from: CR
Repo: hypernetix/hyperspot PR: 0
File: dylint_lints/AGENTS.md:0-0
Timestamp: 2026-01-14T17:18:31.902Z
Learning: Applies to dylint_lints/**/src/lib.rs : Use `declare_late_lint!` with `LateLintPass` and `rustc_hir` when type information or semantic analysis is required
Applied to files:
dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/src/lib.rs
📚 Learning: 2026-01-14T17:18:31.902Z
Learnt from: CR
Repo: hypernetix/hyperspot PR: 0
File: dylint_lints/AGENTS.md:0-0
Timestamp: 2026-01-14T17:18:31.902Z
Learning: Verify tests pass with explicit `-p` flag to ensure correct package tests are running: `cargo test --lib -p <lint_name>`
Applied to files:
dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/Cargo.toml
📚 Learning: 2026-01-14T17:18:31.902Z
Learnt from: CR
Repo: hypernetix/hyperspot PR: 0
File: dylint_lints/AGENTS.md:0-0
Timestamp: 2026-01-14T17:18:31.902Z
Learning: Applies to dylint_lints/ui/*.stderr : Ensure `.stderr` files have comment annotations describing what triggers the lint and include `help:` and `note:` sections
Applied to files:
dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_screaming_snake_case.stderr
🧬 Code graph analysis (6)
dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/pass.rs (16)
dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_camel_case.rs (1)
main(11-11)dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_camel_case.rs (1)
main(11-11)dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_kebab_case.rs (1)
main(11-11)dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_pascal_case.rs (1)
main(11-11)dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_screaming_kebab_case.rs (1)
main(11-11)dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_screaming_snake_case.rs (1)
main(11-11)dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_uppercase.rs (1)
main(11-11)dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_kebab_case.rs (1)
main(11-11)dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_lowercase.rs (1)
main(11-11)dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_pascal_case.rs (1)
main(11-11)dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_screaming_kebab_case.rs (1)
main(11-11)dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_screaming_snake_case.rs (1)
main(11-11)dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_uppercase.rs (1)
main(11-11)dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/pass_field_lowercase.rs (1)
main(11-11)dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/pass_field_snake_case.rs (1)
main(11-11)dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/pass_outside_api.rs (1)
main(11-11)
dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_screaming_kebab_case.rs (16)
dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_camel_case.rs (1)
main(11-11)dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_camel_case.rs (1)
main(11-11)dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_kebab_case.rs (1)
main(11-11)dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_pascal_case.rs (1)
main(11-11)dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_screaming_kebab_case.rs (1)
main(11-11)dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_screaming_snake_case.rs (1)
main(11-11)dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_uppercase.rs (1)
main(11-11)dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_kebab_case.rs (1)
main(11-11)dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_lowercase.rs (1)
main(11-11)dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_pascal_case.rs (1)
main(11-11)dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_screaming_snake_case.rs (1)
main(11-11)dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_uppercase.rs (1)
main(11-11)dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/pass.rs (1)
main(15-15)dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/pass_field_lowercase.rs (1)
main(11-11)dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/pass_field_snake_case.rs (1)
main(11-11)dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/pass_outside_api.rs (1)
main(11-11)
dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/pass_outside_api.rs (16)
dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_camel_case.rs (1)
main(11-11)dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_camel_case.rs (1)
main(11-11)dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_kebab_case.rs (1)
main(11-11)dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_pascal_case.rs (1)
main(11-11)dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_screaming_kebab_case.rs (1)
main(11-11)dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_screaming_snake_case.rs (1)
main(11-11)dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_uppercase.rs (1)
main(11-11)dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_kebab_case.rs (1)
main(11-11)dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_lowercase.rs (1)
main(11-11)dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_pascal_case.rs (1)
main(11-11)dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_screaming_kebab_case.rs (1)
main(11-11)dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_screaming_snake_case.rs (1)
main(11-11)dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_uppercase.rs (1)
main(11-11)dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/pass.rs (1)
main(15-15)dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/pass_field_lowercase.rs (1)
main(11-11)dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/pass_field_snake_case.rs (1)
main(11-11)
dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/src/lib.rs (1)
dylint_lints/lint_utils/src/lib.rs (1)
is_in_api_rest_folder(24-26)
dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_kebab_case.rs (2)
dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_kebab_case.rs (1)
main(11-11)dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/pass_outside_api.rs (1)
main(11-11)
dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_uppercase.rs (16)
dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_camel_case.rs (1)
main(11-11)dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_camel_case.rs (1)
main(11-11)dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_kebab_case.rs (1)
main(11-11)dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_pascal_case.rs (1)
main(11-11)dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_screaming_kebab_case.rs (1)
main(11-11)dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_screaming_snake_case.rs (1)
main(11-11)dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_kebab_case.rs (1)
main(11-11)dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_lowercase.rs (1)
main(11-11)dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_pascal_case.rs (1)
main(11-11)dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_screaming_kebab_case.rs (1)
main(11-11)dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_screaming_snake_case.rs (1)
main(11-11)dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_uppercase.rs (1)
main(11-11)dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/pass.rs (1)
main(15-15)dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/pass_field_lowercase.rs (1)
main(11-11)dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/pass_field_snake_case.rs (1)
main(11-11)dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/pass_outside_api.rs (1)
main(11-11)
🪛 markdownlint-cli2 (0.18.1)
dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/README.md
3-3: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3
(MD001, heading-increment)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
- GitHub Check: UI macro tests (trybuild)
- GitHub Check: Test Suite (ubuntu-latest, rust=stable)
- GitHub Check: Test Suite (windows-latest, rust=stable)
- GitHub Check: Test Suite (macos-latest, rust=stable)
- GitHub Check: Dylint Lints Tests
- GitHub Check: Code Coverage (cargo-llvm-cov)
- GitHub Check: Run Dylint Lints
✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.
|
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
… snake case Signed-off-by: nanoandrew4 <andressmithdev@pm.me>
Signed-off-by: nanoandrew4 <andressmithdev@pm.me>
dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/src/lib.rs
Outdated
Show resolved
Hide resolved
dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_uppercase.rs
Show resolved
Hide resolved
dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_screaming_snake_case.rs
Show resolved
Hide resolved
Signed-off-by: nanoandrew4 <andressmithdev@pm.me>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
🤖 Fix all issues with AI agents
In `@dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/src/lib.rs`:
- Around line 122-134: check_type_rename_all currently only accepts the literal
"snake_case" (rejecting SCREAMING_SNAKE_CASE and UPPERCASE) whereas field-level
logic uses is_valid_case(); update check_type_rename_all to call
is_valid_case(value) instead of comparing value == "snake_case" so the
type-level rename_all validation accepts the same variants (snake_case,
SCREAMING_SNAKE_CASE, uppercase, numeric, and underscores) as is_valid_case;
ensure any error messages/reference still indicate invalid case when
is_valid_case returns false.
In
`@examples/plugin-modules/tenant_resolver/tenant_resolver-gw/src/api/rest/dto.rs`:
- Around line 208-209: The attribute on GetParentsResponseDto incorrectly
includes request; update the modkit_macros::api_dto invocation for the
GetParentsResponseDto struct from api_dto(request, response) to
api_dto(response) so it is only generated as a response DTO (matching
GetChildrenResponseDto) and prevents request-side usage at compile time.
In `@libs/modkit-macros/src/api_dto.rs`:
- Around line 10-20: Update the misleading comment and swap the trait-impl
variables so names match their implementations: change the comment on the
default branch to "Default: neither if neither specified" (or adjust logic
consistently) and swap the implementations so req_trait_impl produces an impl
::modkit::api::api_dto::RequestApiDto for `#name` and resp_trait_impl produces an
impl ::modkit::api::api_dto::ResponseApiDto for `#name`; keep the
serialize/deserialize variable usage (serialize -> ser/Response impl,
deserialize -> de/Request impl) consistent with those names.
🧹 Nitpick comments (4)
libs/modkit/src/api/mod.rs (1)
15-15: LGTM!The new
api_dtomodule correctly expands the public API surface to support macro-driven DTO generation. The module is properly placed alongside other API-related submodules.Consider whether key types from
api_dto(e.g.,RequestApiDto,ResponseApiDtotraits) should be re-exported in this file or in thepreludemodule for convenience, depending on how frequently downstream code needs to reference them directly.modules/system/api_gateway/src/module.rs (1)
694-699: Consider addingDebugderive for consistency.The previous implementation included
Debugwhich was removed during the migration. While not strictly required for the current tests, addingDebugimproves debuggability and maintains consistency with other test DTOs in this PR (e.g.,TestData,LargePayload).🔧 Suggested fix
- #[derive(Clone)] + #[derive(Debug, Clone)] #[modkit_macros::api_dto(request, response)] struct UserEvent {libs/modkit-macros/src/api_dto.rs (1)
21-27:serdeattribute added unconditionally.When neither
requestnorresponseis specified,#[serde(rename_all = "snake_case")]is still added but no serde derives are generated, making the attribute dead code.Consider conditionalizing the serde attribute:
Proposed fix
+ let serde_attr = if serialize || deserialize { + quote! { #[serde(rename_all = "snake_case")] } + } else { + quote! {} + }; quote! { #[derive(`#ser` `#de` utoipa::ToSchema)] - #[serde(rename_all = "snake_case")] + `#serde_attr` `#input` `#req_trait_impl` `#resp_trait_impl` }modules/system/nodes_registry/src/api/rest/dto.rs (1)
36-37: Minor: Inconsistent attribute ordering onOsInfoDto.
OsInfoDtohas the macro attribute before#[derive(...)], while all other DTOs in this file have#[derive(...)]first. This likely doesn't affect functionality, but consider reordering for consistency:-#[modkit_macros::api_dto(request, response)] #[derive(Debug, Clone)] +#[modkit_macros::api_dto(request, response)] pub struct OsInfoDto {
dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/src/lib.rs
Outdated
Show resolved
Hide resolved
examples/plugin-modules/tenant_resolver/tenant_resolver-gw/src/api/rest/dto.rs
Outdated
Show resolved
Hide resolved
🧪 CI InsightsHere's what we observed from your CI run for bef92d4. 🟢 All jobs passed!But CI Insights is watching 👀 |
Signed-off-by: nanoandrew4 <andressmithdev@pm.me>
Signed-off-by: nanoandrew4 <andressmithdev@pm.me>
Signed-off-by: nanoandrew4 <andressmithdev@pm.me>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
🤖 Fix all issues with AI agents
In `@dylint_lints/de02_api_layer/de0203_dtos_must_use_api_dto/README.md`:
- Around line 3-5: The heading level jumps from H1 to H3 for the section titled
"What it does"; change the "### What it does" heading to "## What it does" so it
is a proper H2 under the document's H1 and satisfies MD001 (update the heading
token for the "What it does" section).
In
`@dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/pass_field_screaming_snake_case.stderr`:
- Around line 1-2: The expected stderr span for the DTO serde-rename error is
off-by-one because a preceding comment shifted the serde attribute; update the
test expectation for pass_field_screaming_snake_case to point to the actual
serde attribute location (or simply re-bless the fixture) so the DE0803 message
matches the fixture's attribute span, ensuring the stderr UI file is updated
accordingly.
In
`@dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/pass_field_uppercase.stderr`:
- Around line 1-10: The test output file pass_field_uppercase.stderr currently
contains a DE0803 violation (serde rename uses non-snake_case) which makes this
a failing case; either remove the error output so the pass case truly has an
empty .stderr or move/rename the test to a fail_* case and update the test suite
listing accordingly; locate the DTO test that produced DE0803 (referenced by
pass_field_uppercase.stderr and the serde rename attribute) and either correct
the serde rename to snake_case or convert the test into a failing scenario and
adjust the UI test index so there remains at least one no-violation pass case
with an empty .stderr.
♻️ Duplicate comments (3)
examples/plugin-modules/tenant_resolver/tenant_resolver-gw/src/api/rest/dto.rs (1)
209-210: Consider response-only scope forGetParentsResponseDto.If this type is never deserialized from requests, narrowing it to response-only keeps the surface tighter. Please verify usage before changing.
To verify usage:
#!/bin/bash # Inspect all usages of GetParentsResponseDto to confirm it is only used as a response type. rg -n --type=rust -C3 '\bGetParentsResponseDto\b'modules/file_parser/src/api/rest/dto.rs (2)
81-99: Same casing verification as above for enum variants.
124-161: Same casing verification as above for enum variants.
🧹 Nitpick comments (4)
apps/gts-docs-validator/src/scanner.rs (1)
148-151: Optional: precompile false-positive regexes once.
Regex::newinsideis_false_positiverecompiles every call. Consider a static precompiled set (e.g.,RegexSet+OnceLockor existing lazy helper) to avoid repeated compilation in large scans.♻️ Example (adjust to your MSRV/deps)
+use std::sync::OnceLock; +use regex::RegexSet; @@ +static FALSE_POSITIVE_SET: OnceLock<RegexSet> = OnceLock::new(); + fn is_false_positive(gts_id: &str) -> bool { - for pattern in FALSE_POSITIVE_PATTERNS { - if let Ok(re) = Regex::new(pattern) - && re.is_match(gts_id) { - return true; - } - } - false + let set = FALSE_POSITIVE_SET.get_or_init(|| { + RegexSet::new(FALSE_POSITIVE_PATTERNS).expect("Invalid false-positive regex set") + }); + set.is_match(gts_id) }dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/pass_field_screaming_snake_case.rs (1)
1-1: Consider renaming this fixture tofail_*for clarity.The file name uses
pass_but the fixture is intended to trigger the lint (paired.stderr). Renaming tofail_field_screaming_snake_case.rs(and the.stderrfile) would better match UI-test conventions and reduce confusion.libs/modkit-macros/src/lib.rs (1)
1066-1071: Validateapi_dtoargs to avoid silent typos.Right now any ident is accepted, so a typo (e.g.,
reponse) quietly disables derives. Consider rejecting unknown args with a compile error.💡 Suggested guard
#[proc_macro_attribute] pub fn api_dto(attr: TokenStream, item: TokenStream) -> TokenStream { let attrs = parse_macro_input!(attr with Punctuated::<Ident, Token![,]>::parse_terminated); + for id in &attrs { + if id != "request" && id != "response" { + return syn::Error::new_spanned( + id, + "expected `request` and/or `response`", + ) + .to_compile_error() + .into(); + } + } let input = parse_macro_input!(item as DeriveInput); TokenStream::from(api_dto::expand_api_dto(&attrs, &input)) }dylint_lints/lint_utils/src/lib.rs (1)
90-150: Tightenapi_dtopath matching to avoid false positives.Currently any attribute ending in
api_dtosuppresses lints, even from other crates. Consider requiring bareapi_dtoor a path containingmodkit_macros, and reuse a small helper to avoid duplication in both functions.♻️ Possible refactor
+fn is_api_dto_path(path: &rustc_ast::Path) -> bool { + let segments: Vec<&str> = path.segments.iter().map(|s| s.ident.name.as_str()).collect(); + matches!(segments.as_slice(), ["api_dto"] | [.., "modkit_macros", "api_dto"]) +} + pub fn has_api_dto_attribute(item: &rustc_ast::Item) -> bool { for attr in &item.attrs { // Check for modkit_macros::api_dto or just api_dto if let rustc_ast::AttrKind::Normal(attr_item) = &attr.kind { - let path = &attr_item.item.path; - let segments: Vec<&str> = path.segments.iter().map(|s| s.ident.name.as_str()).collect(); - - // Match: api_dto, modkit_macros::api_dto - if segments.last() == Some(&"api_dto") { + if is_api_dto_path(&attr_item.item.path) { return true; } } } false } @@ - if let rustc_ast::AttrKind::Normal(attr_item) = &attr.kind { - let path = &attr_item.item.path; - let segments: Vec<&str> = path.segments.iter().map(|s| s.ident.name.as_str()).collect(); - - if segments.last() != Some(&"api_dto") { + if let rustc_ast::AttrKind::Normal(attr_item) = &attr.kind { + if !is_api_dto_path(&attr_item.item.path) { continue; }
dylint_lints/de02_api_layer/de0203_dtos_must_use_api_dto/README.md
Outdated
Show resolved
Hide resolved
...ts/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_screaming_snake_case.stderr
Outdated
Show resolved
Hide resolved
examples/plugin-modules/tenant_resolver/tenant_resolver-gw/src/api/rest/dto.rs
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@libs/modkit-macros/src/api_dto.rs`:
- Around line 36-42: The macro emit unconditionally includes #[serde(rename_all
= "snake_case")] which breaks when no serde derives are emitted; update the
api_dto macro so the serde attribute is only inserted into the quote! output
when at least one of the serde trait implementations (req_trait_impl or
resp_trait_impl) is present/ non-empty — i.e., conditionally append the serde
attribute into the generated token stream alongside
req_trait_impl/resp_trait_impl (or guard around the entire attribute insertion)
so it only appears when Serialize or Deserialize is actually derived.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 6
🤖 Fix all issues with AI agents
In `@dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/src/lib.rs`:
- Around line 92-95: Update the diagnostic texts to match the UI fixtures by
replacing occurrences of "invalid case" with "non-snake_case" in the diagnostic
messages emitted by this lint: change the string passed to
diag.primary_message(...) and adjust the accompanying diag.help(...) text where
it references the case wording; ensure you update all occurrences (including the
other block that sets primary_message and help around the second diagnostic and
any test helper references mentioned) so the emitted `.stderr` matches the
fixtures.
- Around line 38-42: The enum branch (ItemKind::Enum handling) currently calls
check_type_rename_all and then iterates variants calling
check_fields(&variant.data) but never validates variant-level serde renames; add
a call to validate each variant's attributes (e.g., invoke a helper like
check_variant_attrs or reuse the existing attribute-checking routine) before
calling check_fields so you run the snake_case check on &variant.attrs for each
variant in enum_def.variants, keeping the calls in the same loop and using the
existing cx context.
- Around line 52-78: find_serde_attribute_value currently only reads direct
value_str() forms and skips nested list forms like rename_all(serialize = "...",
deserialize = "...") and rename(serialize = "..."); update this function to
inspect nested meta_item_list entries for meta items that themselves contain a
list (e.g., rename_all(...) or rename(...)) and iterate those inner nested items
to extract their value_str() values (the serialize/deserialize entries) as well
as the outer direct value_str(); ensure you push (meta_item.span, value) for
each inner string value found so that both rename and the serialize/deserialize
variants are handled by find_serde_attribute_value.
In
`@dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_screaming_snake_case.stderr`:
- Around line 1-10: Update the expected stderr output so the referenced source
file name is correct: replace the incorrect occurrence of
pass_field_screaming_snake_case.rs with fail_field_screaming_snake_case.rs in
the fail_field_screaming_snake_case.stderr content so the error header matches
the test case name and the UI test will compare against the correct expected
file reference.
In
`@dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_uppercase.stderr`:
- Around line 1-10: The stderr snapshot incorrectly references the source file
name "pass_field_uppercase.rs" instead of the actual test source
"fail_field_uppercase.rs"; update the stderr content so the diagnostic header
shows "$DIR/fail_field_uppercase.rs" (the same diagnostic for the #[serde(rename
= "UPPERCASE_FIELD")] field) so the expected output matches the real test file
name.
In
`@dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_screaming_snake_case.stderr`:
- Around line 1-4: Update the stderr fixture so the reported path matches the
test file: change the `$DIR/pass_screaming_snake_case.rs` reference to
`$DIR/fail_screaming_snake_case.rs` in
dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_screaming_snake_case.stderr;
ensure the error line that references the attribute #[serde(rename_all =
"SCREAMING_SNAKE_CASE")] and the DE0803 lint text exactly match the
wording/format used in src/lib.rs so the UI output remains aligned with the lint
message.
...ts/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_screaming_snake_case.stderr
Show resolved
Hide resolved
dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_field_uppercase.stderr
Show resolved
Hide resolved
...nt_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_screaming_snake_case.stderr
Show resolved
Hide resolved
10be5f1 to
661307e
Compare
dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/src/lib.rs
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/src/lib.rs`:
- Around line 82-87: The line using "let Some(inner_meta_item) =
inner_nested.meta_item() && let Some(inner_value) = inner_meta_item.value_str()"
is invalid; replace it with nested conditional pattern matching (e.g., an outer
if let to extract inner_meta_item from inner_nested.meta_item() and an inner if
let to extract inner_value from inner_meta_item.value_str()) so that
results.push((inner_meta_item.span, inner_value.as_str().to_string())) only runs
when both are Some; update the block that iterates inner_list (the code handling
meta_item_list(), inner_nested, inner_meta_item, inner_value and results.push)
accordingly.
🧹 Nitpick comments (1)
dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/ui/fail_enum_variant_rename_camel_case.rs (1)
6-6: Nit: Comment refers to "fields" but these are enum variants.The comments mention "DTO fields" but the lint is checking enum variants here. Consider updating for consistency:
Suggested comment fix
- // Should trigger DE0803 - DTO fields must not use non-snake_case in serde rename/rename_all + // Should trigger DE0803 - DTO enum variants must not use non-snake_case in serde rename/rename_all #[serde(rename = "firstVariant")] FirstVariant, - // Should trigger DE0803 - DTO fields must not use non-snake_case in serde rename/rename_all + // Should trigger DE0803 - DTO enum variants must not use non-snake_case in serde rename/rename_all #[serde(rename = "secondVariant")]Also applies to: 9-9
Signed-off-by: nanoandrew4 <andressmithdev@pm.me>
d544d87 to
86f39b9
Compare
86f39b9 to
308f35d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@libs/modkit-macros/src/lib.rs`:
- Around line 1119-1123: The api_dto macro currently ignores unknown or
duplicate flag idents, so add validation in the api_dto function: parse the
attrs into idents as you already do, then iterate them to check against an
allowed set (e.g., "Serialize", "ResponseApiDto", etc.), detect duplicates, and
if any unknown or duplicate flags are found return a compile error by creating a
syn::Error (e.g., syn::Error::new_spanned) and returning
TokenStream::from(err.to_compile_error()). Update api_dto to perform this
validation before calling api_dto::expand_api_dto and pass validated flags (or
bail early with the compile error) so typos are reported precisely.
32e5de1 to
e2e7b31
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
🤖 Fix all issues with AI agents
In `@dylint_lints/de01_contract_layer/de0104_no_api_dto_in_contract/README.md`:
- Around line 1-21: The top-level heading jumps from `#` to `###` in the README;
change the second heading from `### What it does` (and the subsequent `###`
headings if they represent top-level sections) to `## What it does` to follow
proper Markdown heading level order and ensure consistent document structure;
update any related section headings (e.g., `### Why is this bad?`, `### Known
problems`, `### Example`) to `##` only if they are meant to be the same level as
"What it does".
In `@dylint_lints/de01_contract_layer/de0104_no_api_dto_in_contract/src/lib.rs`:
- Around line 9-60: Replace the use of is_in_contract_path with the AST-based
helper is_in_contract_module_ast in the EarlyLintPass impl for
De0104NoApiDtoInContract: in check_item (and any other places in this file) stop
calling is_in_contract_path(cx.sess().source_map(), item.span) and instead call
is_in_contract_module_ast(cx, item) (or the correct is_in_contract_module_ast
signature that accepts the lint context and the AST Item), so contract detection
uses the AST helper for structs/enums.
In
`@dylint_lints/de01_contract_layer/de0104_no_api_dto_in_contract/ui/with_api_dto.rs`:
- Around line 4-23: The "Should trigger" annotation comments are currently
placed above the attribute lines for the API DTOs; move each comment so it
immediately precedes the item declaration line: place the "Should trigger DE0104
- api_dto in contract" comment directly above the `pub struct User { ... }`
declaration (not above `#[modkit_macros::api_dto(request, response)]`), directly
above the `pub struct Product { ... }` declaration (not above its attribute),
and directly above the `pub enum OrderStatus { ... }` declaration (not above its
attribute); keep the attribute macros (`#[modkit_macros::api_dto(...)]`) on the
line(s) above the declarations as they are.
In
`@dylint_lints/de01_contract_layer/de0104_no_api_dto_in_contract/ui/without_api_dto.rs`:
- Around line 4-9: Move the test annotation comment so it immediately precedes
the item declaration instead of the attribute: take the "Should not trigger
DE0104 - api_dto in contract" comment currently above
#[modkit_macros::api_dto(request, response)] and place it directly above the
`pub struct UserDto { ... }` line (the item declaration) so the annotation sits
on the same line group as the item rather than the attribute.
dylint_lints/de01_contract_layer/de0104_no_api_dto_in_contract/README.md
Outdated
Show resolved
Hide resolved
dylint_lints/de01_contract_layer/de0104_no_api_dto_in_contract/src/lib.rs
Outdated
Show resolved
Hide resolved
dylint_lints/de01_contract_layer/de0104_no_api_dto_in_contract/ui/with_api_dto.rs
Show resolved
Hide resolved
dylint_lints/de01_contract_layer/de0104_no_api_dto_in_contract/ui/without_api_dto.rs
Show resolved
Hide resolved
e2e7b31 to
44b6d8b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@dylint_lints/lint_utils/src/lib.rs`:
- Around line 122-186: The adds_snake_case_rename() method in ApiDtoArgs
currently always returns true, which contradicts the macro behavior that only
applies serde(rename_all = "snake_case") when request or response is present;
update adds_snake_case_rename() to return self.has_request || self.has_response;
also check get_api_dto_args() (which can produce ApiDtoArgs { has_request:false,
has_response:false }) and either add a validation step in the lint to treat the
empty/invalid attribute as absent/error or document that a false/false result
represents an invalid/empty attribute so callers know this case must be rejected
similarly to the macro.
🧹 Nitpick comments (1)
dylint_lints/lint_utils/src/lib.rs (1)
97-120: Consider narrowing api_dto attribute matching.
Matching any path ending inapi_dtocould skip lints for unrelated attributes from other crates. If this should only match unqualifiedapi_dtoormodkit_macros::api_dto, you can tighten the check.♻️ Suggested tweak
- if segments.last() == Some(&"api_dto") { + if segments.last() == Some(&"api_dto") + && (segments.len() == 1 || segments.contains(&"modkit_macros")) + { return true; }
44b6d8b to
04d391a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@dylint_lints/de01_contract_layer/de0104_no_api_dto_in_contract/Cargo.toml`:
- Line 4: The Cargo.toml contains a placeholder authors field ("authors =
[\"authors go here\"]"); either replace that placeholder with the real author
list (e.g., authors = ["Name <email>"]) or remove the authors line entirely (the
field is optional in modern Cargo) to resolve the placeholder value; update the
Cargo.toml's authors entry accordingly.
🧹 Nitpick comments (2)
dylint_lints/lint_utils/src/lib.rs (1)
97-208: Align api_dto arg parsing with macro validation.
get_api_dto_argscurrently ignores unknown/duplicate flags, sois_valid()can betruefor attributes the macro would reject (e.g.,#[api_dto(request, invalid)]). Consider tracking invalid flags and folding that intois_valid()(or returningNone) to keep lint behavior in sync with the proc-macro.♻️ Suggested adjustment
-use rustc_lint::LintContext; +use rustc_lint::LintContext; +use std::collections::HashSet;pub fn get_api_dto_args(item: &rustc_ast::Item) -> Option<ApiDtoArgs> { @@ - let mut has_request = false; - let mut has_response = false; + let mut has_request = false; + let mut has_response = false; + let mut has_invalid = false; + let mut seen = HashSet::new(); @@ - if let Some(ident) = arg.ident() { - match ident.name.as_str() { + if let Some(ident) = arg.ident() { + let name = ident.name.as_str(); + if !seen.insert(name) { + has_invalid = true; + } + match name { "request" => has_request = true, "response" => has_response = true, - _ => {} + _ => has_invalid = true, } } } } return Some(ApiDtoArgs { has_request, has_response, + has_invalid, }); @@ pub struct ApiDtoArgs { pub has_request: bool, pub has_response: bool, + pub has_invalid: bool, } @@ pub fn is_valid(&self) -> bool { - self.has_request || self.has_response + (self.has_request || self.has_response) && !self.has_invalid } }dylint_lints/de01_contract_layer/de0104_no_api_dto_in_contract/Cargo.toml (1)
22-22: Consider using workspace dependency forutoipa.The
utoipadependency is defined in the workspace rootCargo.toml(version 5.4 with macros feature), but this lint crate has a hardcoded version instead of referencing the workspace dependency. Useutoipa.workspace = truefor consistency and easier version management, orutoipa = { workspace = true, features = ["macros"] }if only the macros feature is needed.
dylint_lints/de01_contract_layer/de0104_no_api_dto_in_contract/Cargo.toml
Outdated
Show resolved
Hide resolved
04d391a to
89c8b5b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In `@dylint_lints/lint_utils/src/lib.rs`:
- Around line 97-105: Update the doc comment for the
#[modkit_macros::api_dto(...)] attribute in lib.rs to correct the behavior:
change the line that currently states "`#[serde(rename_all = \"snake_case\")]
(always)`" to indicate that serde(rename_all = "snake_case") is applied only
when `request` or `response` is specified; ensure the comment mentions the
conditional nature and references the `api_dto` attribute and `serde(rename_all
= "snake_case")` so linters and readers understand it is not always applied.
In `@libs/modkit-macros/src/api_dto.rs`:
- Around line 53-72: The generated trait impls (resp_trait_impl and
req_trait_impl) omit the type generics and where-clauses for generic DTOs,
causing compilation failures for types like struct Foo<T>; update the impl
generation to include the input's generics and where-clause (use input.generics
and input.generics.where_clause) so the impls become impl#generics
::modkit::api::api_dto::ResponseApiDto for `#name`#generics `#where_clause` and
similarly for RequestApiDto, ensuring you interpolate the same generics when
referring to the type (`#name`#generics) and attach the where-clause if present.
🧹 Nitpick comments (3)
dylint_lints/de02_api_layer/de0203_dtos_must_use_api_dto/Cargo.toml (2)
5-5: Placeholder description not updated.The description field still contains "description goes here". Consider updating it to describe what this lint enforces (e.g., "Lint to enforce api_dto macro usage on DTOs in the API layer").
Suggested fix
-description = "description goes here" +description = "Lint to enforce api_dto macro usage on DTOs in the API layer"
12-14: Add an example for a passing test case.Currently only the
missing_api_dtoexample is defined, which tests the violation case (missingapi_dtomacro). Include a test case with correct usage of theapi_dtomacro to verify the lint produces no false positives on valid code, with a corresponding empty or near-empty.stderrfile and an additional[[example]]entry inCargo.toml.dylint_lints/de01_contract_layer/de0104_no_api_dto_in_contract/ui/with_api_dto.stderr (1)
1-5: Prefer pointing the diagnostic span at the item declaration (not the attribute).This would align UI tests with the guideline that annotations live on the item line, not the
#[derive]/#[...]line. Update the lint span accordingly and refresh the.stderrexpectations.Based on learnings, ...
Also applies to: 10-15, 18-23
Signed-off-by: nanoandrew4 <andressmithdev@pm.me>
89c8b5b to
561dfd9
Compare
modules/system/nodes_registry/nodes_registry/src/api/rest/dto.rs
Outdated
Show resolved
Hide resolved
dylint_lints/de02_api_layer/de0203_dtos_must_use_api_dto/.gitignore
Outdated
Show resolved
Hide resolved
dylint_lints/de02_api_layer/de0203_dtos_must_use_api_dto/.cargo/config.toml
Outdated
Show resolved
Hide resolved
dylint_lints/de01_contract_layer/de0104_no_api_dto_in_contract/README.md
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
🤖 Fix all issues with AI agents
In
`@dylint_lints/de01_contract_layer/de0101_no_serde_in_contract/.cargo/config.toml`:
- Around line 1-6: The config.toml currently places the linker key at top-level
and comments a [target.'cfg(all())'] block which is invalid; move the linker =
"dylint-link" entry into a literal target table such as
[target.x86_64-unknown-linux-gnu] (or whatever target triple you build for)
instead of top-level or [target.'cfg(all())'], ensuring the linker key lives
under that literal target table in config.toml so Cargo recognizes it.
In
`@dylint_lints/de01_contract_layer/de0102_no_toschema_in_contract/.cargo/config.toml`:
- Around line 1-6: The linker = "dylint-link" entry is at the root level but
must live under a target table; move that key into the [target.'cfg(all())']
section so the file contains a target.'cfg(all())' table with linker =
"dylint-link" (i.e., restore/enable the commented [target.'cfg(all())'] block
and place the linker setting inside it), referencing the linker key and the
[target.'cfg(all())'] table to locate where to change.
In
`@dylint_lints/de02_api_layer/de0202_dtos_not_referenced_outside_api/.cargo/config.toml`:
- Line 6: The top-level linker key is invalid; move the linker setting into a
[build] section so Cargo recognizes it (i.e., create a [build] header and place
linker = "dylint-link" under it), or alternatively use a [target.'cfg(...)']
section for conditional linkers; update the existing standalone linker entry
accordingly so the config uses [build] and the linker symbol is defined there.
In `@dylint_lints/de09_gts_layer/de0901_gts_string_pattern/.cargo/config.toml`:
- Around line 1-6: The top-level setting linker = "dylint-link" is invalid in
Cargo config and will be ignored; move this key into a proper section header
(for example add a [build] section or place it inside an existing target table
like [target.'cfg(all())']) so the linker directive is recognized; update the
config so the unique symbol linker = "dylint-link" is nested under a section
header (e.g., [build] or [target.'cfg(all())']) rather than at top level.
♻️ Duplicate comments (2)
libs/modkit-macros/src/api_dto.rs (1)
60-74: Handle generics in generated trait impls.For generic DTOs (e.g.,
struct Foo<T>), the generatedimpl RequestApiDto for Foo {}/impl ResponseApiDto for Foo {}will not compile because generics and where-clauses are omitted.Proposed fix
pub fn expand_api_dto(args: &Punctuated<Ident, Token![,]>, input: &DeriveInput) -> TokenStream { if let Err(err) = validate_flags(args) { return err; } let has_request = args.iter().any(|id| id == "request"); let has_response = args.iter().any(|id| id == "response"); if !has_request && !has_response { return quote! { compile_error!("api_dto macro requires at least one of 'request' or 'response' arguments"); }; } let (serialize, deserialize) = (has_response, has_request); let name = &input.ident; + let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl(); let ser = if serialize { quote! { ::serde::Serialize, } } else { quote! {} }; let resp_trait_impl = if serialize { - quote! { impl ::modkit::api::api_dto::ResponseApiDto for `#name` {} } + quote! { impl `#impl_generics` ::modkit::api::api_dto::ResponseApiDto for `#name` `#ty_generics` `#where_clause` {} } } else { quote! {} }; let de = if deserialize { quote! { ::serde::Deserialize, } } else { quote! {} }; let req_trait_impl = if deserialize { - quote! { impl ::modkit::api::api_dto::RequestApiDto for `#name` {} } + quote! { impl `#impl_generics` ::modkit::api::api_dto::RequestApiDto for `#name` `#ty_generics` `#where_clause` {} } } else { quote! {} };dylint_lints/de01_contract_layer/de0103_no_http_types_in_contract/.cargo/config.toml (1)
1-6: Same config pattern as other lint crates.This follows the same global linker configuration pattern. The same verification note about potentially needing a
[build]section header applies here.
🧹 Nitpick comments (2)
modules/system/nodes_registry/nodes_registry/src/api/rest/dto.rs (1)
1-1: Minor: InconsistentUuidusage.Line 1 imports
Uuid, but lines 23 and 85 use the fully qualifieduuid::Uuid. Consider using the importedUuidconsistently throughout for cleaner code.Suggested fix
- pub node_id: uuid::Uuid, + pub node_id: Uuid,Also applies to: 6-6, 23-23, 85-85
libs/modkit-macros/src/api_dto.rs (1)
83-89: Use fully qualified path forutoipa::ToSchemafor consistency.The serde traits use fully qualified paths (
::serde::Serialize,::serde::Deserialize), bututoipa::ToSchemadoes not. For consistency and to avoid potential shadowing issues in user code, consider using::utoipa::ToSchema.Proposed fix
quote! { - #[derive(`#ser` `#de` utoipa::ToSchema)] + #[derive(`#ser` `#de` ::utoipa::ToSchema)] `#serde_attr` `#input` `#req_trait_impl` `#resp_trait_impl` }
dylint_lints/de01_contract_layer/de0101_no_serde_in_contract/.cargo/config.toml
Outdated
Show resolved
Hide resolved
dylint_lints/de01_contract_layer/de0102_no_toschema_in_contract/.cargo/config.toml
Outdated
Show resolved
Hide resolved
dylint_lints/de02_api_layer/de0202_dtos_not_referenced_outside_api/.cargo/config.toml
Show resolved
Hide resolved
dylint_lints/de09_gts_layer/de0901_gts_string_pattern/.cargo/config.toml
Outdated
Show resolved
Hide resolved
Signed-off-by: nanoandrew4 <andressmithdev@pm.me>
a29e99b to
ca12fa2
Compare
dylint_lints/de08_rest_api_conventions/de0803_api_snake_case/src/lib.rs
Outdated
Show resolved
Hide resolved
| } | ||
|
|
||
| // Must not have consecutive underscores | ||
| if s.contains("__") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks like edge cases, but why are we denying __ and _hello_?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've never seen __ (double spacing) used in a request/response, if it shows up it is likely a typo IMO. A field that starts with a leading underscore is usually private/internal, and should probably not be part of a DTO. They just enforce a more predictable convention, but if we do have valid use cases for variables starting with an underscore, I can do away with that validation
Signed-off-by: nanoandrew4 <andressmithdev@pm.me>
Signed-off-by: nanoandrew4 <andressmithdev@pm.me>
Partially addresses #225
Other lints were considered but rejected for now in favor of enforcing the guidelines, especially around documentation, with macros at compile time.
Summary by CodeRabbit
New Features
Improvements
Documentation
✏️ Tip: You can customize this high-level summary in your review settings.