ryo_executor/engine/impls/
variant.rs1use ryo_mutations::basic::{AddVariantMutation, RemoveVariantMutation};
4use ryo_mutations::MutationResult;
5use ryo_source::pure::{PureItem, PureVariant};
6
7use crate::engine::{ASTMutationContext, ASTRegApply, ModificationType, MutationEvent};
8
9impl ASTRegApply for AddVariantMutation {
10 fn apply_to_registry(&self, ctx: &mut ASTMutationContext) -> MutationResult {
11 let target_id = self.enum_id;
12
13 let item = match ctx.ast_registry.get(target_id) {
15 Some(item) => item.clone(),
16 None => {
17 return MutationResult {
18 mutation_type: "AddVariant".to_string(),
19 changes: 0,
20 description: format!("AST not found for {:?}", target_id),
21 };
22 }
23 };
24
25 let new_item = match item {
27 PureItem::Enum(mut e) => {
28 if e.variants.iter().any(|v| v.name == self.variant_name) {
30 return MutationResult {
31 mutation_type: "AddVariant".to_string(),
32 changes: 0,
33 description: format!(
34 "Variant '{}' already exists in {:?}",
35 self.variant_name, target_id
36 ),
37 };
38 }
39
40 e.variants.push(PureVariant {
41 attrs: Vec::new(),
42 name: self.variant_name.clone(),
43 fields: self.fields.clone(),
44 discriminant: None,
45 });
46 PureItem::Enum(e)
47 }
48 _ => {
49 return MutationResult {
50 mutation_type: "AddVariant".to_string(),
51 changes: 0,
52 description: format!("{:?} is not an enum", target_id),
53 };
54 }
55 };
56
57 ctx.set_ast(target_id, new_item);
59
60 ctx.emit(MutationEvent::SymbolModified {
62 id: target_id,
63 modification: ModificationType::VariantAdded(self.variant_name.clone()),
64 });
65
66 MutationResult {
67 mutation_type: "AddVariant".to_string(),
68 changes: 1,
69 description: format!("Added variant '{}' to {:?}", self.variant_name, target_id),
70 }
71 }
72}
73
74impl ASTRegApply for RemoveVariantMutation {
75 fn apply_to_registry(&self, ctx: &mut ASTMutationContext) -> MutationResult {
76 let target_id = self.enum_id;
77
78 let item = match ctx.ast_registry.get(target_id) {
80 Some(item) => item.clone(),
81 None => {
82 return MutationResult {
83 mutation_type: "RemoveVariant".to_string(),
84 changes: 0,
85 description: format!("AST not found for {:?}", target_id),
86 };
87 }
88 };
89
90 let (new_item, removed) = match item {
92 PureItem::Enum(mut e) => {
93 let original_len = e.variants.len();
94 e.variants.retain(|v| v.name != self.variant_name);
95 let removed = e.variants.len() < original_len;
96 (PureItem::Enum(e), removed)
97 }
98 _ => {
99 return MutationResult {
100 mutation_type: "RemoveVariant".to_string(),
101 changes: 0,
102 description: format!("{:?} is not an enum", target_id),
103 };
104 }
105 };
106
107 if removed {
108 ctx.set_ast(target_id, new_item);
110
111 ctx.emit(MutationEvent::SymbolModified {
113 id: target_id,
114 modification: ModificationType::VariantRemoved(self.variant_name.clone()),
115 });
116 }
117
118 MutationResult {
119 mutation_type: "RemoveVariant".to_string(),
120 changes: if removed { 1 } else { 0 },
121 description: if removed {
122 format!(
123 "Removed variant '{}' from {:?}",
124 self.variant_name, target_id
125 )
126 } else {
127 format!(
128 "Variant '{}' not found in {:?}",
129 self.variant_name, target_id
130 )
131 },
132 }
133 }
134}