1pub mod builtin;
9pub mod schema;
10
11pub use builtin::BuiltinRules;
12pub use schema::{CodemodRule, RuleConfig};
13
14use std::path::Path;
15
16use crate::error::CodemodError;
17
18pub fn load_rule(path: &Path) -> crate::Result<CodemodRule> {
29 let content = std::fs::read_to_string(path).map_err(CodemodError::Io)?;
30 let rule: CodemodRule = serde_yaml::from_str(&content)
31 .map_err(|e| CodemodError::Rule(format!("Failed to parse rule file: {e}")))?;
32 rule.validate()?;
33 Ok(rule)
34}
35
36pub fn save_rule(rule: &CodemodRule, path: &Path) -> crate::Result<()> {
43 let content = serde_yaml::to_string(rule)
44 .map_err(|e| CodemodError::Rule(format!("Failed to serialize rule: {e}")))?;
45 std::fs::write(path, content).map_err(CodemodError::Io)?;
46 Ok(())
47}
48
49#[cfg(test)]
50mod tests {
51 use super::*;
52 use crate::rule::schema::RulePattern;
53 use std::fs;
54
55 #[test]
56 fn test_save_and_load_rule() {
57 let tmp = std::env::temp_dir().join("codemod_test_rule.yaml");
58
59 let rule = CodemodRule {
60 name: "test-rule".into(),
61 description: "A test rule".into(),
62 language: "rust".into(),
63 version: "1.0".into(),
64 pattern: RulePattern {
65 before: "println!($var1)".into(),
66 after: "log::info!($var1)".into(),
67 },
68 config: RuleConfig::default(),
69 };
70
71 save_rule(&rule, &tmp).unwrap();
72 let loaded = load_rule(&tmp).unwrap();
73
74 assert_eq!(loaded.name, "test-rule");
75 assert_eq!(loaded.pattern.before, "println!($var1)");
76 assert_eq!(loaded.pattern.after, "log::info!($var1)");
77
78 let _ = fs::remove_file(&tmp);
79 }
80}