Skip to content

Commit 5f29b45

Browse files
author
Jeshua ben Joseph
committed
docs: Add rationale for Guardian's existence and its role in code quality enforcement
1 parent b171e5b commit 5f29b45

File tree

2 files changed

+44
-65
lines changed

2 files changed

+44
-65
lines changed

README.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -563,6 +563,24 @@ Licensed under the MIT License. See [LICENSE](LICENSE) for details.
563563

564564
See [CHANGELOG.md](CHANGELOG.md) for release history.
565565

566+
## Why Guardian Exists
567+
568+
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.
569+
570+
Guardian was born from a simple realization: **Compilable ≠ Complete**.
571+
572+
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.
573+
574+
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.
575+
576+
Guardian stands watch so you can focus on creating, knowing that nothing incomplete will slip through.
577+
578+
Built with love for the craft of software development.
579+
580+
Done and done.
581+
582+
— ARIA Systems
583+
566584
## Support
567585

568586
- **Documentation**: [docs.rs/rust-guardian](https://docs.rs/rust-guardian)

src/patterns/mod.rs

Lines changed: 26 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -746,7 +746,7 @@ impl PatternEngine {
746746
matches: Vec<(u32, u32, String, String)>,
747747
}
748748

749-
impl<'a> Visit<'_> for MacroVisitor<'a> {
749+
impl Visit<'_> for MacroVisitor<'_> {
750750
fn visit_macro(&mut self, mac: &syn::Macro) {
751751
if let Some(ident) = mac.path.get_ident() {
752752
let macro_name = ident.to_string();
@@ -909,14 +909,14 @@ impl PatternEngine {
909909
match method_name.as_str() {
910910
"unwrap" => {
911911
// unwrap() calls are always problematic
912-
let (line, col, context) = (1, 1, format!(".unwrap()"));
912+
let (line, col, context) = (1, 1, ".unwrap()".to_string());
913913
self.matches.push((line, col, "unwrap".to_string(), context));
914914
}
915915
"expect" => {
916916
// Check if expect() has a meaningful message
917917
if method_call.args.is_empty() {
918918
// expect() without any message
919-
let (line, col, context) = (1, 1, format!(".expect()"));
919+
let (line, col, context) = (1, 1, ".expect()".to_string());
920920
self.matches.push((line, col, "expect".to_string(), context));
921921
} else if let syn::Expr::Lit(syn::ExprLit { lit: syn::Lit::Str(lit_str), .. }) = &method_call.args[0] {
922922
let message = lit_str.value();
@@ -945,16 +945,15 @@ impl PatternEngine {
945945
}
946946

947947
/// Find import patterns using regex matching on use statements
948-
fn find_import_pattern_matches(&self, syntax_tree: &syn::File, content: &str, regex: &regex::Regex) -> Vec<(u32, u32, String, String)> {
948+
fn find_import_pattern_matches(&self, syntax_tree: &syn::File, _content: &str, regex: &regex::Regex) -> Vec<(u32, u32, String, String)> {
949949
use syn::visit::Visit;
950950

951951
struct ImportVisitor<'a> {
952952
regex: &'a regex::Regex,
953-
content: &'a str,
954953
matches: Vec<(u32, u32, String, String)>,
955954
}
956955

957-
impl<'a> Visit<'_> for ImportVisitor<'a> {
956+
impl Visit<'_> for ImportVisitor<'_> {
958957
fn visit_item_use(&mut self, use_item: &syn::ItemUse) {
959958
// Convert the use statement back to string for regex matching
960959
let use_string = format!("use {};", quote::quote!(#use_item).to_string().trim_start_matches("use "));
@@ -973,7 +972,6 @@ impl PatternEngine {
973972

974973
let mut visitor = ImportVisitor {
975974
regex,
976-
content,
977975
matches: Vec::new(),
978976
};
979977

@@ -1180,45 +1178,37 @@ impl PatternEngine {
11801178

11811179
impl Visit<'_> for PublicDocsVisitor {
11821180
fn visit_item_fn(&mut self, func: &syn::ItemFn) {
1183-
if matches!(func.vis, syn::Visibility::Public(_)) {
1184-
if !self.has_doc_comment(&func.attrs) {
1185-
let fn_name = func.sig.ident.to_string();
1186-
let (line, col, context) = (1, 1, format!("pub fn {}", fn_name));
1187-
self.matches.push((line, col, format!("fn {}", fn_name), context));
1188-
}
1181+
if matches!(func.vis, syn::Visibility::Public(_)) && !self.has_doc_comment(&func.attrs) {
1182+
let fn_name = func.sig.ident.to_string();
1183+
let (line, col, context) = (1, 1, format!("pub fn {}", fn_name));
1184+
self.matches.push((line, col, format!("fn {}", fn_name), context));
11891185
}
11901186
syn::visit::visit_item_fn(self, func);
11911187
}
11921188

11931189
fn visit_item_struct(&mut self, item_struct: &syn::ItemStruct) {
1194-
if matches!(item_struct.vis, syn::Visibility::Public(_)) {
1195-
if !self.has_doc_comment(&item_struct.attrs) {
1196-
let struct_name = item_struct.ident.to_string();
1197-
let (line, col, context) = (1, 1, format!("pub struct {}", struct_name));
1198-
self.matches.push((line, col, format!("struct {}", struct_name), context));
1199-
}
1190+
if matches!(item_struct.vis, syn::Visibility::Public(_)) && !self.has_doc_comment(&item_struct.attrs) {
1191+
let struct_name = item_struct.ident.to_string();
1192+
let (line, col, context) = (1, 1, format!("pub struct {}", struct_name));
1193+
self.matches.push((line, col, format!("struct {}", struct_name), context));
12001194
}
12011195
syn::visit::visit_item_struct(self, item_struct);
12021196
}
12031197

12041198
fn visit_item_enum(&mut self, item_enum: &syn::ItemEnum) {
1205-
if matches!(item_enum.vis, syn::Visibility::Public(_)) {
1206-
if !self.has_doc_comment(&item_enum.attrs) {
1207-
let enum_name = item_enum.ident.to_string();
1208-
let (line, col, context) = (1, 1, format!("pub enum {}", enum_name));
1209-
self.matches.push((line, col, format!("enum {}", enum_name), context));
1210-
}
1199+
if matches!(item_enum.vis, syn::Visibility::Public(_)) && !self.has_doc_comment(&item_enum.attrs) {
1200+
let enum_name = item_enum.ident.to_string();
1201+
let (line, col, context) = (1, 1, format!("pub enum {}", enum_name));
1202+
self.matches.push((line, col, format!("enum {}", enum_name), context));
12111203
}
12121204
syn::visit::visit_item_enum(self, item_enum);
12131205
}
12141206

12151207
fn visit_item_trait(&mut self, item_trait: &syn::ItemTrait) {
1216-
if matches!(item_trait.vis, syn::Visibility::Public(_)) {
1217-
if !self.has_doc_comment(&item_trait.attrs) {
1218-
let trait_name = item_trait.ident.to_string();
1219-
let (line, col, context) = (1, 1, format!("pub trait {}", trait_name));
1220-
self.matches.push((line, col, format!("trait {}", trait_name), context));
1221-
}
1208+
if matches!(item_trait.vis, syn::Visibility::Public(_)) && !self.has_doc_comment(&item_trait.attrs) {
1209+
let trait_name = item_trait.ident.to_string();
1210+
let (line, col, context) = (1, 1, format!("pub trait {}", trait_name));
1211+
self.matches.push((line, col, format!("trait {}", trait_name), context));
12221212
}
12231213
syn::visit::visit_item_trait(self, item_trait);
12241214
}
@@ -1243,16 +1233,15 @@ impl PatternEngine {
12431233
}
12441234

12451235
/// Find functions that are too long
1246-
fn find_long_functions(&self, syntax_tree: &syn::File, content: &str, threshold: u32) -> Vec<(u32, u32, String, u32, String)> {
1236+
fn find_long_functions(&self, syntax_tree: &syn::File, _content: &str, threshold: u32) -> Vec<(u32, u32, String, u32, String)> {
12471237
use syn::visit::Visit;
12481238

1249-
struct LongFunctionVisitor<'a> {
1250-
content: &'a str,
1239+
struct LongFunctionVisitor {
12511240
threshold: u32,
12521241
matches: Vec<(u32, u32, String, u32, String)>,
12531242
}
12541243

1255-
impl<'a> Visit<'_> for LongFunctionVisitor<'a> {
1244+
impl Visit<'_> for LongFunctionVisitor {
12561245
fn visit_item_fn(&mut self, func: &syn::ItemFn) {
12571246
let fn_name = func.sig.ident.to_string();
12581247

@@ -1268,7 +1257,7 @@ impl PatternEngine {
12681257
}
12691258
}
12701259

1271-
impl<'a> LongFunctionVisitor<'a> {
1260+
impl LongFunctionVisitor {
12721261
fn count_function_lines(&self, block: &syn::Block) -> u32 {
12731262
// Simple line counting - count non-empty, non-comment lines
12741263
let block_str = format!("{}", quote::quote!(#block));
@@ -1279,7 +1268,6 @@ impl PatternEngine {
12791268
}
12801269

12811270
let mut visitor = LongFunctionVisitor {
1282-
content,
12831271
threshold,
12841272
matches: Vec::new(),
12851273
};
@@ -1507,34 +1495,7 @@ impl PatternEngine {
15071495
visitor.matches
15081496
}
15091497

1510-
/// Find direct mindset module access
1511-
fn find_direct_mindset_access(&self, syntax_tree: &syn::File) -> Vec<(u32, u32, String, String)> {
1512-
use syn::visit::Visit;
1513-
1514-
struct MindsetAccessVisitor {
1515-
matches: Vec<(u32, u32, String, String)>,
1516-
}
1517-
1518-
impl Visit<'_> for MindsetAccessVisitor {
1519-
fn visit_item_use(&mut self, use_item: &syn::ItemUse) {
1520-
let use_string = format!("{}", quote::quote!(#use_item));
1521-
1522-
if use_string.contains("mindset") && !use_string.contains("domain") {
1523-
let (line, col, context) = (1, 1, use_string.clone());
1524-
self.matches.push((line, col, use_string, context));
1525-
}
1526-
1527-
syn::visit::visit_item_use(self, use_item);
1528-
}
1529-
}
1530-
1531-
let mut visitor = MindsetAccessVisitor {
1532-
matches: Vec::new(),
1533-
};
1534-
1535-
visitor.visit_file(syntax_tree);
1536-
visitor.matches
1537-
}
1498+
15381499

15391500
/// Find generics without trait bounds
15401501
fn find_generics_without_bounds(&self, syntax_tree: &syn::File) -> Vec<(u32, u32, String, String)> {

0 commit comments

Comments
 (0)