ryo_executor/executor/registry/converters/
match_arm.rs1use crate::engine::ASTRegApply;
4use crate::executor::registry::converters::ResolveTargetSymbol;
5use crate::executor::registry::{ConvertError, MutationConverter};
6use crate::executor::spec::MutationSpec;
7use ryo_analysis::AnalysisContext;
8use ryo_mutations::{AddMatchArmMutation, RemoveMatchArmMutation, ReplaceMatchArmMutation};
9
10#[derive(Debug, Clone, Default)]
12pub struct MatchArmConverter;
13
14impl MatchArmConverter {
15 pub fn new() -> Self {
16 Self
17 }
18}
19
20impl ResolveTargetSymbol for MatchArmConverter {}
22
23impl MutationConverter for MatchArmConverter {
24 fn spec_kinds(&self) -> &'static [&'static str] {
25 &["AddMatchArm", "RemoveMatchArm", "ReplaceMatchArm"]
26 }
27
28 fn convert_v2(
29 &self,
30 spec: &MutationSpec,
31 ctx: &AnalysisContext,
32 ) -> Result<Vec<Box<dyn ASTRegApply>>, ConvertError> {
33 match spec {
34 MutationSpec::AddMatchArm {
35 target,
36 enum_name,
37 pattern,
38 body,
39 } => {
40 let fn_id = self.resolve_target_symbol(target, ctx)?;
41
42 let mutation = AddMatchArmMutation::new(
43 fn_id,
44 enum_name.clone(),
45 pattern.clone(),
46 body.clone(),
47 );
48 Ok(vec![Box::new(mutation)])
49 }
50 MutationSpec::RemoveMatchArm {
51 target,
52 enum_name,
53 pattern,
54 } => {
55 let fn_id = self.resolve_target_symbol(target, ctx)?;
56
57 let mutation =
58 RemoveMatchArmMutation::new(fn_id, enum_name.clone(), pattern.clone());
59 Ok(vec![Box::new(mutation)])
60 }
61 MutationSpec::ReplaceMatchArm {
62 target,
63 enum_name,
64 old_pattern,
65 new_pattern,
66 new_body,
67 } => {
68 let fn_id = self.resolve_target_symbol(target, ctx)?;
69
70 let mutation = ReplaceMatchArmMutation::new(
71 fn_id,
72 enum_name.clone(),
73 old_pattern.clone(),
74 new_pattern.clone(),
75 new_body.clone(),
76 );
77 Ok(vec![Box::new(mutation)])
78 }
79 _ => Err(ConvertError::TypeMismatch {
80 expected: "AddMatchArm, RemoveMatchArm, or ReplaceMatchArm",
81 actual: spec.kind_name().to_string(),
82 }),
83 }
84 }
85}
86
87#[cfg(test)]
88mod tests {
89 use super::*;
90 use crate::executor::spec::MutationTargetSymbol;
91 use ryo_analysis::SymbolPath;
92
93 #[test]
94 fn test_match_arm_converter_spec_kinds() {
95 let converter = MatchArmConverter::new();
96 assert_eq!(
97 converter.spec_kinds(),
98 &["AddMatchArm", "RemoveMatchArm", "ReplaceMatchArm"]
99 );
100 }
101
102 #[test]
103 fn test_match_arm_converter_can_handle() {
104 let converter = MatchArmConverter::new();
105
106 let spec = MutationSpec::AddMatchArm {
107 target: MutationTargetSymbol::ByPath(Box::new(
108 SymbolPath::parse("test_crate::handlers::process_status").unwrap(),
109 )),
110 enum_name: "Status".to_string(),
111 pattern: "Status::Cancelled".to_string(),
112 body: "todo!()".to_string(),
113 };
114 assert!(converter.can_handle(&spec));
115 }
116}