ryo_executor/engine/impls/
field.rs1use ryo_mutations::basic::{AddFieldMutation, RemoveFieldMutation};
4use ryo_mutations::MutationResult;
5use ryo_source::pure::{PureField, PureFields, PureItem, PureType, PureVis};
6
7use crate::engine::{ASTMutationContext, ASTRegApply, ModificationType};
8
9impl ASTRegApply for AddFieldMutation {
10 fn apply_to_registry(&self, ctx: &mut ASTMutationContext) -> MutationResult {
11 let target_id = self.struct_id;
12
13 let ast = match ctx.get_ast_mut(target_id) {
15 Some(ast) => ast,
16 None => {
17 return MutationResult {
18 mutation_type: "AddField".to_string(),
19 changes: 0,
20 description: format!("AST not found for {:?}", target_id),
21 };
22 }
23 };
24
25 if let PureItem::Struct(s) = ast {
27 if let PureFields::Named(fields) = &s.fields {
29 if fields.iter().any(|f| f.name == self.field_name) {
30 return MutationResult {
31 mutation_type: "AddField".to_string(),
32 changes: 0,
33 description: format!("Field '{}' already exists", self.field_name),
34 };
35 }
36 }
37
38 let new_field = PureField {
40 attrs: Vec::new(),
41 vis: if self.is_pub {
42 PureVis::Public
43 } else {
44 PureVis::Private
45 },
46 name: self.field_name.clone(),
47 ty: PureType::Path(self.field_type.clone()),
48 };
49
50 match &mut s.fields {
52 PureFields::Named(fields) => {
53 fields.push(new_field);
54 }
55 PureFields::Unit => {
56 s.fields = PureFields::Named(vec![new_field]);
57 }
58 PureFields::Tuple(_) => {
59 return MutationResult {
60 mutation_type: "AddField".to_string(),
61 changes: 0,
62 description: "Cannot add named field to tuple struct".to_string(),
63 };
64 }
65 }
66
67 ctx.emit_modified(
68 target_id,
69 ModificationType::FieldAdded(self.field_name.clone()),
70 );
71
72 MutationResult {
73 mutation_type: "AddField".to_string(),
74 changes: 1,
75 description: format!("Added field '{}'", self.field_name),
76 }
77 } else {
78 MutationResult {
79 mutation_type: "AddField".to_string(),
80 changes: 0,
81 description: format!("{:?} is not a struct", target_id),
82 }
83 }
84 }
85}
86
87impl ASTRegApply for RemoveFieldMutation {
88 fn apply_to_registry(&self, ctx: &mut ASTMutationContext) -> MutationResult {
89 let target_id = self.struct_id;
90
91 let ast = match ctx.get_ast_mut(target_id) {
93 Some(ast) => ast,
94 None => {
95 return MutationResult {
96 mutation_type: "RemoveField".to_string(),
97 changes: 0,
98 description: format!("AST not found for {:?}", target_id),
99 };
100 }
101 };
102
103 if let PureItem::Struct(s) = ast {
105 if let PureFields::Named(fields) = &mut s.fields {
106 let original_len = fields.len();
107 fields.retain(|f| f.name != self.field_name);
108
109 if fields.len() < original_len {
110 ctx.emit_modified(
111 target_id,
112 ModificationType::FieldRemoved(self.field_name.clone()),
113 );
114
115 return MutationResult {
116 mutation_type: "RemoveField".to_string(),
117 changes: 1,
118 description: format!("Removed field '{}'", self.field_name),
119 };
120 }
121 }
122
123 MutationResult {
124 mutation_type: "RemoveField".to_string(),
125 changes: 0,
126 description: format!("Field '{}' not found", self.field_name),
127 }
128 } else {
129 MutationResult {
130 mutation_type: "RemoveField".to_string(),
131 changes: 0,
132 description: format!("{:?} is not a struct", target_id),
133 }
134 }
135 }
136}