ricecoder_refactoring/
types.rs

1//! Core data types for the refactoring engine
2
3use serde::{Deserialize, Serialize};
4use std::collections::HashMap;
5use std::path::PathBuf;
6
7/// A refactoring operation
8#[derive(Debug, Clone, Serialize, Deserialize)]
9pub struct Refactoring {
10    /// Unique identifier for the refactoring
11    pub id: String,
12    /// Type of refactoring to perform
13    pub refactoring_type: RefactoringType,
14    /// Target of the refactoring
15    pub target: RefactoringTarget,
16    /// Options for the refactoring
17    pub options: RefactoringOptions,
18}
19
20/// Types of refactoring operations
21#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
22pub enum RefactoringType {
23    /// Rename a symbol
24    Rename,
25    /// Extract code into a new function/method
26    Extract,
27    /// Inline a function/method
28    Inline,
29    /// Move a symbol to another location
30    Move,
31    /// Change function signature
32    ChangeSignature,
33    /// Remove unused code
34    RemoveUnused,
35    /// Simplify code
36    Simplify,
37}
38
39/// Target of a refactoring operation
40#[derive(Debug, Clone, Serialize, Deserialize)]
41pub struct RefactoringTarget {
42    /// File containing the target
43    pub file: PathBuf,
44    /// Symbol name to refactor
45    pub symbol: String,
46    /// Range in the file (line:col - line:col)
47    pub range: Option<String>,
48}
49
50/// Options for refactoring operations
51#[derive(Debug, Clone, Serialize, Deserialize)]
52pub struct RefactoringOptions {
53    /// Perform a dry run without applying changes
54    pub dry_run: bool,
55    /// Automatically rollback on failure
56    pub auto_rollback_on_failure: bool,
57    /// Run tests after refactoring
58    pub run_tests_after: bool,
59    /// Additional options as key-value pairs
60    pub extra: HashMap<String, String>,
61}
62
63impl Default for RefactoringOptions {
64    fn default() -> Self {
65        Self {
66            dry_run: false,
67            auto_rollback_on_failure: true,
68            run_tests_after: false,
69            extra: HashMap::new(),
70        }
71    }
72}
73
74/// Result of a refactoring operation
75#[derive(Debug, Clone, Serialize, Deserialize)]
76pub struct RefactoringResult {
77    /// Changes made by the refactoring
78    pub changes: Vec<FileChange>,
79    /// Impact analysis of the changes
80    pub impact: Option<String>,
81    /// Validation result
82    pub validation: Option<String>,
83    /// Whether the refactoring succeeded
84    pub success: bool,
85}
86
87/// A change to a file
88#[derive(Debug, Clone, Serialize, Deserialize)]
89pub struct FileChange {
90    /// Path to the file
91    pub file: PathBuf,
92    /// Original content
93    pub original: String,
94    /// New content
95    pub new: String,
96    /// Type of change
97    pub change_type: ChangeType,
98}
99
100/// Type of change to a file
101#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
102pub enum ChangeType {
103    /// File was modified
104    Modified,
105    /// File was created
106    Created,
107    /// File was deleted
108    Deleted,
109    /// File was renamed
110    Renamed,
111}
112
113impl std::fmt::Display for RefactoringType {
114    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
115        match self {
116            RefactoringType::Rename => write!(f, "rename"),
117            RefactoringType::Extract => write!(f, "extract"),
118            RefactoringType::Inline => write!(f, "inline"),
119            RefactoringType::Move => write!(f, "move"),
120            RefactoringType::ChangeSignature => write!(f, "change_signature"),
121            RefactoringType::RemoveUnused => write!(f, "remove_unused"),
122            RefactoringType::Simplify => write!(f, "simplify"),
123        }
124    }
125}
126
127/// Result of validation
128#[derive(Debug, Clone, Serialize, Deserialize)]
129pub struct ValidationResult {
130    /// Whether validation passed
131    pub passed: bool,
132    /// Validation errors
133    pub errors: Vec<String>,
134    /// Validation warnings
135    pub warnings: Vec<String>,
136}
137
138/// Configuration for a language's refactoring rules
139#[derive(Debug, Clone, Serialize, Deserialize)]
140pub struct RefactoringConfig {
141    /// Language name
142    pub language: String,
143    /// File extensions for this language
144    pub extensions: Vec<String>,
145    /// Refactoring rules
146    pub rules: Vec<RefactoringRule>,
147    /// Refactoring transformations
148    pub transformations: Vec<RefactoringTransformation>,
149    /// Optional provider reference (e.g., LSP server name)
150    pub provider: Option<String>,
151}
152
153impl RefactoringConfig {
154    /// Validate the configuration
155    pub fn validate(&self) -> crate::error::Result<()> {
156        if self.language.is_empty() {
157            return Err(crate::error::RefactoringError::ConfigError(
158                "Language name cannot be empty".to_string(),
159            ));
160        }
161        if self.extensions.is_empty() {
162            return Err(crate::error::RefactoringError::ConfigError(
163                "At least one file extension must be specified".to_string(),
164            ));
165        }
166        Ok(())
167    }
168
169    /// Create a generic fallback configuration for a language
170    pub fn generic_fallback(language: &str) -> Self {
171        Self {
172            language: language.to_string(),
173            extensions: vec![],
174            rules: vec![],
175            transformations: vec![],
176            provider: None,
177        }
178    }
179}
180
181/// A refactoring rule
182#[derive(Debug, Clone, Serialize, Deserialize)]
183pub struct RefactoringRule {
184    /// Rule name
185    pub name: String,
186    /// Pattern to match
187    pub pattern: String,
188    /// Type of refactoring
189    pub refactoring_type: RefactoringType,
190    /// Whether the rule is enabled
191    pub enabled: bool,
192}
193
194/// A refactoring transformation
195#[derive(Debug, Clone, Serialize, Deserialize)]
196pub struct RefactoringTransformation {
197    /// Transformation name
198    pub name: String,
199    /// Pattern to match
200    pub from_pattern: String,
201    /// Replacement pattern
202    pub to_pattern: String,
203    /// Description
204    pub description: String,
205}
206
207/// Impact analysis result
208#[derive(Debug, Clone, Serialize, Deserialize)]
209pub struct ImpactAnalysis {
210    /// Affected files
211    pub affected_files: Vec<PathBuf>,
212    /// Affected symbols
213    pub affected_symbols: Vec<String>,
214    /// Risk level
215    pub risk_level: RiskLevel,
216    /// Estimated effort (1-10)
217    pub estimated_effort: u8,
218}
219
220/// Risk level for a refactoring
221#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
222pub enum RiskLevel {
223    /// Low risk
224    Low,
225    /// Medium risk
226    Medium,
227    /// High risk
228    High,
229}
230
231/// Preview of refactoring changes
232#[derive(Debug, Clone, Serialize, Deserialize)]
233pub struct RefactoringPreview {
234    /// Changes to be made
235    pub changes: Vec<FileChange>,
236    /// Impact analysis
237    pub impact: ImpactAnalysis,
238    /// Estimated time in seconds
239    pub estimated_time_seconds: u32,
240}
241
242/// Backup information
243#[derive(Debug, Clone, Serialize, Deserialize)]
244pub struct BackupInfo {
245    /// Backup ID
246    pub id: String,
247    /// Timestamp of backup
248    pub timestamp: String,
249    /// Backed up files (path -> content)
250    pub files: HashMap<PathBuf, String>,
251}
252
253impl std::str::FromStr for RefactoringType {
254    type Err = String;
255
256    fn from_str(s: &str) -> Result<Self, Self::Err> {
257        match s {
258            "rename" => Ok(RefactoringType::Rename),
259            "extract" => Ok(RefactoringType::Extract),
260            "inline" => Ok(RefactoringType::Inline),
261            "move" => Ok(RefactoringType::Move),
262            "change_signature" => Ok(RefactoringType::ChangeSignature),
263            "remove_unused" => Ok(RefactoringType::RemoveUnused),
264            "simplify" => Ok(RefactoringType::Simplify),
265            _ => Err(format!("Unknown refactoring type: {}", s)),
266        }
267    }
268}