ricecoder_refactoring/patterns/
mod.rs

1//! Refactoring patterns for reusable transformations
2
3pub mod store;
4pub mod validator;
5pub mod matcher;
6pub mod exporter;
7
8pub use store::PatternStore;
9pub use validator::PatternValidator;
10pub use matcher::PatternMatcher;
11pub use exporter::PatternExporter;
12
13use serde::{Deserialize, Serialize};
14use std::collections::HashMap;
15
16/// A reusable refactoring pattern
17#[derive(Debug, Clone, Serialize, Deserialize)]
18pub struct RefactoringPattern {
19    /// Pattern name
20    pub name: String,
21    /// Pattern description
22    pub description: String,
23    /// Pattern template with placeholders
24    pub template: String,
25    /// Pattern parameters
26    pub parameters: Vec<PatternParameter>,
27    /// Pattern scope (global or project)
28    pub scope: PatternScope,
29}
30
31/// A pattern parameter
32#[derive(Debug, Clone, Serialize, Deserialize)]
33pub struct PatternParameter {
34    /// Parameter name
35    pub name: String,
36    /// Placeholder in template (e.g., {{old_name}})
37    pub placeholder: String,
38    /// Parameter description
39    pub description: String,
40}
41
42/// Pattern scope
43#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
44pub enum PatternScope {
45    /// Global pattern
46    Global,
47    /// Project-specific pattern
48    Project,
49}
50
51/// Pattern application with parameter values
52#[derive(Debug, Clone)]
53pub struct PatternApplication {
54    /// The pattern being applied
55    pub pattern: RefactoringPattern,
56    /// Parameter values
57    pub parameters: HashMap<String, String>,
58}
59
60impl PatternApplication {
61    /// Apply the pattern to code
62    pub fn apply(&self, _code: &str) -> crate::error::Result<String> {
63        let mut result = self.pattern.template.clone();
64
65        for (name, value) in &self.parameters {
66            let placeholder = format!("{{{{{}}}}}", name);
67            result = result.replace(&placeholder, value);
68        }
69
70        Ok(result)
71    }
72}
73
74#[cfg(test)]
75mod tests {
76    use super::*;
77
78    #[test]
79    fn test_pattern_application() -> crate::error::Result<()> {
80        let pattern = RefactoringPattern {
81            name: "rename".to_string(),
82            description: "Rename a function".to_string(),
83            template: "fn {{old_name}}() {} -> fn {{new_name}}() {}".to_string(),
84            parameters: vec![
85                PatternParameter {
86                    name: "old_name".to_string(),
87                    placeholder: "{{old_name}}".to_string(),
88                    description: "Old function name".to_string(),
89                },
90                PatternParameter {
91                    name: "new_name".to_string(),
92                    placeholder: "{{new_name}}".to_string(),
93                    description: "New function name".to_string(),
94                },
95            ],
96            scope: PatternScope::Global,
97        };
98
99        let mut params = HashMap::new();
100        params.insert("old_name".to_string(), "foo".to_string());
101        params.insert("new_name".to_string(), "bar".to_string());
102
103        let app = PatternApplication {
104            pattern,
105            parameters: params,
106        };
107
108        let result = app.apply("fn foo() {} -> fn bar() {}")?;
109        assert!(result.contains("foo"));
110        assert!(result.contains("bar"));
111
112        Ok(())
113    }
114}