ricecoder_refactoring/adapters/
generic.rs1use crate::error::Result;
4use crate::providers::{RefactoringAnalysis, RefactoringProvider};
5use crate::types::{Refactoring, RefactoringType, ValidationResult};
6use regex::Regex;
7
8pub struct GenericRefactoringProvider;
10
11impl GenericRefactoringProvider {
12 pub fn new() -> Self {
14 Self
15 }
16
17 pub fn apply_text_transformation(code: &str, from_pattern: &str, to_pattern: &str) -> Result<String> {
19 match Regex::new(from_pattern) {
20 Ok(re) => Ok(re.replace_all(code, to_pattern).to_string()),
21 Err(_) => {
22 Ok(code.replace(from_pattern, to_pattern))
24 }
25 }
26 }
27
28 pub fn apply_rename(code: &str, old_name: &str, new_name: &str) -> Result<String> {
30 let pattern = format!(r"\b{}\b", regex::escape(old_name));
32 match Regex::new(&pattern) {
33 Ok(re) => Ok(re.replace_all(code, new_name).to_string()),
34 Err(_) => {
35 Ok(code.replace(old_name, new_name))
37 }
38 }
39 }
40
41 pub fn count_occurrences(code: &str, pattern: &str) -> usize {
43 match Regex::new(pattern) {
44 Ok(re) => re.find_iter(code).count(),
45 Err(_) => code.matches(pattern).count(),
46 }
47 }
48}
49
50impl Default for GenericRefactoringProvider {
51 fn default() -> Self {
52 Self::new()
53 }
54}
55
56impl RefactoringProvider for GenericRefactoringProvider {
57 fn analyze_refactoring(
58 &self,
59 _code: &str,
60 _language: &str,
61 _refactoring_type: RefactoringType,
62 ) -> Result<RefactoringAnalysis> {
63 Ok(RefactoringAnalysis {
65 applicable: true,
66 reason: None,
67 complexity: 3, })
69 }
70
71 fn apply_refactoring(
72 &self,
73 code: &str,
74 _language: &str,
75 refactoring: &Refactoring,
76 ) -> Result<String> {
77 match refactoring.refactoring_type {
79 RefactoringType::Rename => {
80 Ok(code.to_string())
83 }
84 RefactoringType::RemoveUnused => {
85 Ok(code.to_string())
87 }
88 _ => {
89 Ok(code.to_string())
91 }
92 }
93 }
94
95 fn validate_refactoring(
96 &self,
97 original: &str,
98 refactored: &str,
99 _language: &str,
100 ) -> Result<ValidationResult> {
101 let mut errors = vec![];
102 let mut warnings = vec![];
103
104 if refactored.is_empty() {
106 errors.push("Refactored code cannot be empty".to_string());
107 }
108
109 if original == refactored {
111 warnings.push("No changes were made".to_string());
112 }
113
114 let open_braces = refactored.matches('{').count();
116 let close_braces = refactored.matches('}').count();
117 if open_braces != close_braces {
118 warnings.push("Brace mismatch detected".to_string());
119 }
120
121 Ok(ValidationResult {
122 passed: errors.is_empty(),
123 errors,
124 warnings,
125 })
126 }
127}
128
129#[cfg(test)]
130mod tests {
131 use super::*;
132 use crate::types::{RefactoringOptions, RefactoringTarget};
133 use std::path::PathBuf;
134
135 #[test]
136 fn test_generic_provider_analyze() -> Result<()> {
137 let provider = GenericRefactoringProvider::new();
138 let analysis = provider.analyze_refactoring("code", "unknown", RefactoringType::Rename)?;
139
140 assert!(analysis.applicable);
141 assert_eq!(analysis.complexity, 3);
142
143 Ok(())
144 }
145
146 #[test]
147 fn test_generic_provider_validate() -> Result<()> {
148 let provider = GenericRefactoringProvider::new();
149 let result = provider.validate_refactoring("original", "refactored", "unknown")?;
150
151 assert!(result.passed);
152
153 Ok(())
154 }
155
156 #[test]
157 fn test_generic_provider_validate_empty() -> Result<()> {
158 let provider = GenericRefactoringProvider::new();
159 let result = provider.validate_refactoring("original", "", "unknown")?;
160
161 assert!(!result.passed);
162 assert!(!result.errors.is_empty());
163
164 Ok(())
165 }
166
167 #[test]
168 fn test_generic_provider_apply_refactoring() -> Result<()> {
169 let provider = GenericRefactoringProvider::new();
170 let refactoring = Refactoring {
171 id: "test".to_string(),
172 refactoring_type: RefactoringType::Rename,
173 target: RefactoringTarget {
174 file: PathBuf::from("test.txt"),
175 symbol: "old".to_string(),
176 range: None,
177 },
178 options: RefactoringOptions::default(),
179 };
180
181 let result = provider.apply_refactoring("code with old", "unknown", &refactoring)?;
182 assert_eq!(result, "code with old");
183
184 Ok(())
185 }
186}