A Rust tool that uses tree-sitter to parse Rust files and check that documentation comments (docstrings) follow PEP 257 conventions as much as possible within the context of Rust code.
- Tree-sitter parsing: Uses tree-sitter-rust for accurate AST-based parsing
- PEP 257 compliance: Checks documentation comments against adapted PEP 257 rules
- Multiple comment styles: Supports
///,/** */, and#[doc = "..."]documentation styles - Multiple output formats: Text and JSON output formats
- Comprehensive coverage: Checks functions, structs, enums, traits, impl blocks, modules, and constants
- Command-line interface: Easy-to-use CLI with various options
The tool implements the following PEP 257 rules adapted for Rust:
- D100: Missing docstring in public items
- D201: No blank lines allowed before function docstring (adapted)
- D202: No blank lines allowed after function docstring (adapted)
- D205: 1 blank line required between summary line and description
- D300: Use consistent comment style (adapted for Rust
///comments) - D301: Raw string suggestion for backslashes
- D302: Unicode content detection
- D400: First line should end with a period
- D401: First line should be in imperative mood
- D402: First line should not be the function's signature
- D403: First word should be properly capitalized
- Rust 1.70 or later
- Cargo
git clone <repository-url>
cd pep257
cargo build --releaseThe binary will be available at target/release/pep257.
# Basic usage
pep257 check src/main.rs
# Or using the --file flag
pep257 --file src/main.rs# Check current directory
pep257 check-dir .
# Check recursively
pep257 check-dir src --recursivepep257 --file src/main.rs --warnings# Default text format
pep257 --file src/main.rs
# JSON format
pep257 --file src/main.rs --format jsonpep257 --file src/main.rs --no-failsrc/main.rs:1:1 error [D403]: First word of the first line should be properly capitalized src/main.rs:1:1 error [D400]: First line should end with a period src/main.rs:15:1 error [D100]: Missing docstring in public function
{
"file": "src/main.rs",
"violations": [
{
"column": 1,
"line": 1,
"message": "First word of the first line should be properly capitalized",
"rule": "D403",
"severity": "error"
},
{
"column": 1,
"line": 1,
"message": "First line should end with a period",
"rule": "D400",
"severity": "error"
}
]
}The tool supports all three Rust documentation comment styles:
/// Calculate the sum of two numbers.
///
/// This function takes two integers and returns their sum.
fn add(a: i32, b: i32) -> i32 {
a + b
}/**
* Calculate the sum of two numbers.
*
* This function takes two integers and returns their sum.
*/
fn add(a: i32, b: i32) -> i32 {
a + b
}#[doc = "Calculate the sum of two numbers."]
fn add(a: i32, b: i32) -> i32 {
a + b
}
// Multi-line with multiple attributes
#[doc = "Calculate the sum of two numbers."]
#[doc = ""]
#[doc = "This function takes two integers and returns their sum."]
fn add_detailed(a: i32, b: i32) -> i32 {
a + b
}Based on PEP 257 adapted for Rust:
-
Write concise one-line summaries: The first line should be a brief summary ending with a period.
-
Use imperative mood: Start with verbs like "Calculate", "Create", "Return", not "Calculates" or "This function calculates".
-
Proper capitalization: Start the first word with a capital letter.
-
Separate summary from description: Use a blank line between the summary and detailed description.
-
Avoid signatures: Don't repeat the function signature in the docstring.
/// Calculate the area of a rectangle.
///
/// Takes width and height as parameters and returns the calculated area.
/// Both parameters must be positive numbers.
fn calculate_area(width: f64, height: f64) -> f64 {
width * height
}
/// Represents a point in 2D space.
struct Point {
x: f64,
y: f64,
}/// calculates the area of a rectangle // Missing period, not capitalized
fn calculate_area(width: f64, height: f64) -> f64 {
width * height
}
/// This function calculates the area // Not imperative mood
fn calculate_area(width: f64, height: f64) -> f64 {
width * height
}
/// calculate_area(width: f64, height: f64) -> f64 // Contains signature
fn calculate_area(width: f64, height: f64) -> f64 {
width * height
}
fn undocumented_function() { // Missing docstring
// This will trigger D100
}You can integrate this tool into your CI/CD pipeline:
# In your CI script
cargo run --bin pep257 -- check-dir src --recursive
if [ $? -ne 0 ]; then
echo "Documentation style violations found!"
exit 1
fiAdd to your .git/hooks/pre-commit:
#!/bin/sh
cargo run --bin pep257 -- check-dir src --recursive- Rust-specific adaptation: Some PEP 257 rules don't directly apply to Rust, so they've been adapted
- Public vs. private: Currently checks all items, not just public ones (this could be enhanced)
- Module-level docs: Limited support for module-level documentation
- Macro documentation: Does not check documentation for macros
- Fork the repository
- Create a feature branch
- Add tests for new functionality
- Ensure all tests pass:
cargo test - Submit a pull request
This project is licensed under the MIT License - see the LICENSE file for details.
- Built on top of tree-sitter and tree-sitter-rust
- Inspired by Python's pep257 tool
- Follows the PEP 257 docstring conventions where applicable