ryo_executor/executor/registry/converters/
trait_.rs1use crate::engine::ASTRegApply;
9use crate::executor::registry::converter::{ConvertError, MutationConverter};
10use crate::executor::registry::converters::ResolveTargetSymbol;
11use crate::executor::spec::MutationSpec;
12use ryo_analysis::AnalysisContext;
13use ryo_mutations::{EnumToTraitMutation, ExtractTraitMutation, InlineTraitMutation};
14
15pub struct TraitConverter;
17
18impl TraitConverter {
19 pub fn new() -> Self {
20 Self
21 }
22}
23
24impl Default for TraitConverter {
25 fn default() -> Self {
26 Self::new()
27 }
28}
29
30impl ResolveTargetSymbol for TraitConverter {}
32
33impl MutationConverter for TraitConverter {
34 fn spec_kinds(&self) -> &'static [&'static str] {
35 &["ExtractTrait", "InlineTrait", "EnumToTrait"]
36 }
37
38 fn convert_v2(
39 &self,
40 spec: &MutationSpec,
41 ctx: &AnalysisContext,
42 ) -> Result<Vec<Box<dyn ASTRegApply>>, ConvertError> {
43 match spec {
44 MutationSpec::ExtractTrait {
45 target: target_symbol,
46 trait_name,
47 methods,
48 } => {
49 let symbol_id = self.resolve_target_symbol(target_symbol, ctx)?;
51 let mut mutation = ExtractTraitMutation::new(symbol_id, trait_name);
52 if let Some(m) = methods {
53 mutation = mutation.with_methods(m.clone());
54 }
55 Ok(vec![Box::new(mutation)])
56 }
57
58 MutationSpec::InlineTrait {
59 target: target_symbol,
60 struct_name,
61 remove_trait,
62 } => {
63 let symbol_id = self.resolve_target_symbol(target_symbol, ctx)?;
65 let mut mutation = InlineTraitMutation::new(symbol_id, struct_name);
66 if !remove_trait {
67 mutation = mutation.keep_trait();
68 }
69 Ok(vec![Box::new(mutation)])
70 }
71
72 MutationSpec::EnumToTrait {
73 target: target_symbol,
74 trait_name,
75 remove_enum,
76 strategy,
77 match_handling,
78 } => {
79 let symbol_id = self.resolve_target_symbol(target_symbol, ctx)?;
81
82 let mut mutation = EnumToTraitMutation::from_symbol_id(symbol_id)
83 .with_strategy(*strategy)
84 .with_match_handling(*match_handling);
85 if let Some(t_name) = trait_name {
86 mutation = mutation.with_trait_name(t_name);
87 }
88 if !remove_enum {
89 mutation = mutation.keep_enum();
90 }
91 Ok(vec![Box::new(mutation)])
92 }
93
94 _ => Err(ConvertError::TypeMismatch {
95 expected: "ExtractTrait, InlineTrait, or EnumToTrait",
96 actual: spec.kind_name().to_string(),
97 }),
98 }
99 }
100}
101
102#[cfg(test)]
103mod tests {
104 use super::*;
105
106 #[test]
107 fn test_trait_converter_spec_kinds() {
108 let converter = TraitConverter::new();
109 assert_eq!(
110 converter.spec_kinds(),
111 &["ExtractTrait", "InlineTrait", "EnumToTrait"]
112 );
113 }
114}