Rust Guardian
Dynamic code quality enforcement that prevents incomplete or placeholder code from reaching production.
Rust Guardian is a self-contained, production-ready crate for comprehensive code quality analysis. It provides both a CLI tool and library API for detecting placeholder code, enforcing architectural boundaries, and maintaining code quality standards across any Rust project.
Features
- 🔍 Pattern-Based Analysis: Detect TODO comments, unimplemented macros, and placeholder code
- 🏗️ Architecture Enforcement: Validate architectural principles and bounded context integrity
- ⚡ High Performance: Parallel processing with intelligent caching
- 🤖 Automation Integration: Async API for CI/CD and automated workflows
- 📊 Multiple Output Formats: Human, JSON, JUnit, SARIF, GitHub Actions
- ⚙️ Flexible Configuration: YAML-based pattern customization
- 🔄 Watch Mode: Real-time validation during development
- 🎯 Zero Dependencies: Self-contained with no external crate dependencies
Quick Start
Installation
# Install from crates.io
# Or add to your project
CLI Usage
# Check entire project
# Check specific paths
# Output formats
# Filter by severity
# Performance and caching
# File filtering
# Configuration and debugging
# Watch mode for development
# Configuration management
# Rule management
# Cache management
Library Usage
use ;
use PathBuf;
async
Configuration
Create guardian.yaml in your project root:
version: "1.0"
paths:
patterns:
# Exclude patterns (like .gitignore)
- "target/" # Ignore target directory
- "**/*.md" # Ignore all markdown files
- "*.generated.rs" # Ignore generated files
- "!README.md" # But include README.md
- "**/tests/**" # Ignore test directories
# Include patterns (with !) - override previous excludes
- "!src/core/**/*.rs" # Always check core modules
- "!src/api/**/*.rs" # Always check API modules
# Optional: Support .guardianignore file
ignore_file: ".guardianignore" # Like .gitignore but for guardian
patterns:
placeholders:
severity: error
enabled: true
rules:
- id: todo_comments
type: regex
pattern: '\b(TODO|FIXME|HACK|XXX|BUG|REFACTOR)\b'
message: "Placeholder comment detected: {match}"
- id: unimplemented_macros
type: ast
pattern: |
macro_call:
- unimplemented
- todo
- unreachable
- panic
message: "Unfinished macro {macro_name}! found"
exclude_if:
- attribute: "#[test]"
architectural_violations:
severity: error
enabled: true
rules:
- id: hardcoded_paths
type: regex
pattern: '(/tmp/|/var/|/home/)[^"]*"'
message: "Hardcoded path found - use configuration instead"
Path Pattern Configuration
Rust Guardian uses .gitignore-style patterns for intuitive file filtering:
Pattern Syntax
-
No prefix: Exclude pattern (like .gitignore)
- "target/" # Exclude target directory - "**/*.md" # Exclude all markdown files -
!prefix: Include pattern (override previous excludes)- "!README.md" # Include README.md even if *.md was excluded - "!docs/**/*.md" # Include all docs markdown files -
Glob patterns supported:
*- Matches anything except/**- Matches any number of directories?- Matches single character[abc]- Matches any character in brackets
Pattern Resolution
Patterns are evaluated in order, with later patterns overriding earlier ones:
paths:
patterns:
- "**/*.rs" # Include all Rust files
- "target/**" # But exclude target directory
- "**/tests/**" # And exclude test directories
- "!integration-tests/**" # But include integration-tests
- "!src/core/**/*.rs" # Always include core modules
.guardianignore File Support
Like .gitignore but for Guardian:
# .guardianignore in project root
!
# Directory-specific .guardianignore
- Works exactly like
.gitignore - Can be placed in any directory
- Patterns relative to file location
- Multiple files merged during traversal
Pattern Types
Regex Patterns
Text-based pattern matching using regular expressions:
- id: temporary_markers
type: regex
pattern: '(for now|temporary|placeholder|stub|dummy|fake)'
case_sensitive: false
message: "Temporary implementation marker found"
AST Patterns
Rust syntax tree analysis for semantic understanding:
- id: empty_ok_return
type: ast
pattern: |
function:
body:
return: Ok(())
min_statements: 1
message: "Function returns Ok(()) with no implementation"
Semantic Patterns
Advanced code analysis for architectural compliance:
- id: direct_internal_access
type: import_analysis
forbidden_imports:
"src/server":
message: "Direct internal access violates module boundaries"
Automation Integration
For CI/CD pipelines and automated workflows that need to validate code before committing:
use ;
async
CI/CD Integration
GitHub Actions
- name: Code Quality Check
run: |
rust-guardian check --format github --severity error >> $GITHUB_STEP_SUMMARY
rust-guardian check --format json --severity error > guardian-report.json
- name: Upload Results
uses: actions/upload-artifact@v3
with:
name: guardian-report
path: guardian-report.json
GitLab CI
code_quality:
script:
- rust-guardian check --format junit --severity error > guardian-report.xml
artifacts:
reports:
junit: guardian-report.xml
Performance
Rust Guardian is designed for speed:
- Parallel Processing: Analyzes multiple files concurrently using rayon
- Intelligent Caching: Skips unchanged files using hash-based caching
- Memory Efficient: Streams large files, limits memory usage
- Fast Startup: Embedded patterns, no external dependencies
Benchmarks on a typical medium-sized Rust project (5,000 files, 500k LOC):
- Cold Run: ~1.2 seconds
- Warm Run (cached): ~0.2 seconds
- Memory Usage: ~100MB peak
Watch Mode
For real-time feedback during development:
Features:
- Debounced Updates: Groups rapid file changes
- Hot Configuration Reload: Updates patterns without restart
- Focused Output: Only shows changed files
- Performance Optimized: Incremental analysis
Output Formats
Human (Default)
Colored terminal output with context:
❌ Code Quality Violations Found
📁 src/api/handlers.rs
45:12:todo_comments [error] Placeholder comment detected: TODO
│ // TODO: Implement error handling
📊 Summary: 1 error, 2 warnings in 156 files (1.2s)
Agent Format
Simplified format for automated processing and agent consumption:
[45:src/api/handlers.rs]
Placeholder comment detected: TODO
[102:src/lib.rs]
Traditional unit tests found - consider integration tests for better architectural validation
[67:src/models.rs]
Function returns Ok(()) with no meaningful implementation
JSON
Machine-readable format for tooling:
JUnit XML
For CI/CD test result integration:
File: src/lib.rs:45:12
Context: // TODO: Implement error handling
Rule Reference
Built-in Pattern Categories
Placeholders (placeholders)
todo_comments: TODO, FIXME, HACK, XXX, BUG, REFACTOR commentstemporary_implementation: "for now", "placeholder", "stub" markersunimplemented_macros: unimplemented!(), todo!(), unreachable!(), panic!()
Incomplete Implementations (incomplete_implementations)
empty_ok_return: Functions returning Ok(()) with no logicminimal_function: Functions with insufficient implementation
Architectural Violations (architectural_violations)
domain_header_missing: Missing domain module headersboundary_violation: Module boundary violations in importshardcoded_paths: Hardcoded file paths instead of configuration
Testing Requirements (testing_requirements)
untested_public_function: Public functions lacking test coverage
Severity Levels
- Error: Blocks commits, fails CI/CD builds
- Warning: Informational, doesn't fail builds by default
- Info: Documentation and suggestions
Advanced Usage
Advanced Path Configuration Examples
Complex filtering with override patterns:
paths:
patterns:
# Start with broad exclusions
- "**/target/**" # Exclude all target directories
- "**/*.md" # Exclude all markdown
- "**/tests/**" # Exclude test directories
- "vendor/" # Exclude vendor
# Then selectively include what we want
- "!README.md" # But include README
- "!docs/**/*.md" # Include all documentation
- "!integration-tests/" # Include integration tests specifically
- "!src/core/**" # Always analyze core modules
# Final specific exclusions
- "src/core/benches/" # But not benchmarks in core
Project-specific example:
paths:
patterns:
# Legacy code - exclude by default
- "legacy/**"
- "deprecated/**"
# But include specific legacy modules being refactored
- "!legacy/auth/"
- "!legacy/models/"
# Generated code exclusions
- "**/*.generated.rs"
- "**/*.pb.rs" # Protocol buffers
- "src/schema.rs" # Diesel schema
# But include hand-maintained generated code
- "!src/api/generated/custom_*.rs"
Custom Patterns
Extend with project-specific patterns:
patterns:
custom:
severity: warning
enabled: true
rules:
- id: deprecated_api_usage
type: regex
pattern: 'deprecated_function\('
message: "Use new_function() instead of deprecated_function()"
- id: missing_error_context
type: ast
pattern: |
function:
returns: Result
body:
missing: ".context("
message: "Result should include error context"
Programmatic Configuration
use ;
let mut config = default;
config.add_rule;
let guardian = with_config?;
Integration with Pre-commit Hooks
.pre-commit-hooks.yaml:
repos:
- repo: local
hooks:
- id: rust-guardian
name: Rust Guardian
entry: rust-guardian check --severity error
language: system
files: '\.(rs|toml|yaml)$'
pass_filenames: false
Contributing
We welcome contributions! Please see CONTRIBUTING.md for guidelines.
Development Setup
Running Tests
# Unit tests
# Integration tests
# Performance benchmarks
License
Licensed under the MIT License. See LICENSE for details.
Changelog
See CHANGELOG.md for release history.
Why Guardian Exists
Every Rust developer knows the gap between "it compiles" and "it's complete." This gap becomes a chasm when using AI assistance or working in teams. AI generates syntactically perfect code filled with TODOs and placeholders. Teams merge "temporary" solutions that become permanent. Technical debt accumulates invisibly.
Guardian was born from a simple realization: Compilable ≠ Complete.
We built Guardian because we believe every line of code deserves to be finished, not just functional. Whether written by human, AI, or collaborative development, code should be complete, intentional, and ready for production.
This tool enforces what code reviews miss, what AI forgets to finish, and what "we'll fix it later" never addresses. It's not just about catching TODOs - it's about ensuring that every function that compiles actually does what it promises.
Guardian stands watch so you can focus on creating, knowing that nothing incomplete will slip through.
Built with love for the craft of software development.
Done and done.
— The Rust Guardian Team
Support
- Documentation: docs.rs/rust-guardian
- Issues: GitHub Issues
- Discussions: GitHub Discussions