ryo_suggest/safety/mod.rs
1//! Safety suggestions - Detect code safety improvement opportunities
2//!
3//! This module provides suggestions for improving code safety by detecting
4//! potential panic points and suggesting safer alternatives.
5//!
6//! # Available Suggestions
7//!
8//! | Code | Name | Description |
9//! |------|------|-------------|
10//! | RS101 | `UnwrapToExpect` | Convert unwrap() to expect() with descriptive message |
11//! | RS102 | `StringErrorType` | Detect string-based error types, suggest thiserror |
12//!
13//! # Architecture
14//!
15//! Safety suggestions analyze AST patterns to find potential panic points:
16//!
17//! ```text
18//! ┌─────────────────────────────────────────────────────────────────┐
19//! │ Safety Suggest Detection │
20//! │ ──────────────────────── │
21//! │ │
22//! │ Detection: AST traversal for method calls │
23//! │ ├─ unwrap() on Option/Result │
24//! │ ├─ Filter: skip if function returns Option/Result (use ?) │
25//! │ └─ Context extraction for message generation │
26//! │ │
27//! │ Message Generation: │
28//! │ ├─ Variable context: "config should be Some" │
29//! │ ├─ Field context: "self.data should be initialized" │
30//! │ └─ Method chain: "get_user() should return Some" │
31//! └─────────────────────────────────────────────────────────────────┘
32//! ```
33
34mod string_error_type;
35mod unwrap_to_expect;
36
37pub use string_error_type::StringErrorType;
38pub use unwrap_to_expect::UnwrapToExpect;
39
40use crate::{LintSeverity, OpportunityContext, OpportunityId, SuggestLocation, SuggestOpportunity};
41
42/// Trait for safety-related suggestions
43///
44/// Provides common utilities for safety detection patterns.
45pub trait SafetySuggest {
46 /// Get the rule code (e.g., "RS101")
47 fn code(&self) -> &'static str;
48
49 /// Get the default severity for this safety issue
50 fn default_severity(&self) -> LintSeverity {
51 LintSeverity::Warning
52 }
53
54 /// Create a safety opportunity with standard context
55 fn create_safety_opportunity(
56 &self,
57 id: OpportunityId,
58 targets: Vec<ryo_analysis::SymbolId>,
59 location: SuggestLocation,
60 message: String,
61 suggestion: String,
62 confidence: f32,
63 ) -> SuggestOpportunity {
64 SuggestOpportunity::new(
65 id,
66 targets,
67 location,
68 message,
69 confidence,
70 OpportunityContext::Lint {
71 code: self.code().to_string(),
72 rule: self.code().to_string(),
73 severity: self.default_severity(),
74 suggestion: Some(suggestion),
75 expected: None,
76 actual: None,
77 },
78 )
79 }
80}