ryo_executor/engine/impls/
struct_def.rs1use ryo_mutations::basic::{AddStructMutation, RemoveStructMutation};
4use ryo_mutations::MutationResult;
5use ryo_source::pure::{
6 PureAttrMeta, PureAttribute, PureField, PureFields, PureGenerics, PureItem, PureStruct,
7 PureType, PureVis,
8};
9use ryo_symbol::SymbolKind;
10
11use crate::engine::{ASTMutationContext, ASTRegApply};
12
13impl ASTRegApply for AddStructMutation {
14 fn apply_to_registry(&self, ctx: &mut ASTMutationContext) -> MutationResult {
15 let module_id = self.parent;
17
18 if ctx.symbol_registry.kind(module_id) != Some(SymbolKind::Mod) {
20 return MutationResult {
21 mutation_type: "AddStruct".to_string(),
22 changes: 0,
23 description: format!("Symbol {} is not a module", module_id),
24 };
25 }
26
27 let exists = ctx
29 .symbol_registry
30 .iter()
31 .filter(|(id, _)| ctx.symbol_registry.kind(*id) == Some(SymbolKind::Struct))
32 .any(|(_, path)| path.name() == self.name);
33
34 if exists {
35 return MutationResult {
36 mutation_type: "AddStruct".to_string(),
37 changes: 0,
38 description: format!("Struct '{}' already exists", self.name),
39 };
40 }
41
42 let attrs = if !self.derives.is_empty() {
44 vec![PureAttribute {
45 path: "derive".to_string(),
46 meta: PureAttrMeta::List(self.derives.join(", ")),
47 is_inner: false,
48 }]
49 } else {
50 vec![]
51 };
52
53 let fields: Vec<PureField> = self
55 .fields
56 .iter()
57 .map(|f| PureField {
58 attrs: vec![],
59 vis: if f.is_pub {
60 PureVis::Public
61 } else {
62 PureVis::Private
63 },
64 name: f.name.clone(),
65 ty: PureType::Path(f.ty.clone()),
66 })
67 .collect();
68
69 let struct_item = PureStruct {
70 attrs,
71 vis: if self.is_pub {
72 PureVis::Public
73 } else {
74 PureVis::Private
75 },
76 name: self.name.clone(),
77 generics: PureGenerics::default(),
78 fields: if fields.is_empty() {
79 PureFields::Unit
80 } else {
81 PureFields::Named(fields)
82 },
83 };
84
85 let struct_path = ctx
87 .symbol_registry
88 .path(module_id)
89 .and_then(|p| p.child(&self.name).ok());
90
91 if let Some(path) = struct_path {
92 if let Ok(struct_id) = ctx.symbol_registry.register(path, SymbolKind::Struct) {
93 ctx.ast_registry
94 .set(struct_id, PureItem::Struct(struct_item));
95
96 return MutationResult {
97 mutation_type: "AddStruct".to_string(),
98 changes: 1,
99 description: format!("Added struct '{}'", self.name),
100 };
101 }
102 }
103
104 MutationResult {
105 mutation_type: "AddStruct".to_string(),
106 changes: 0,
107 description: format!("Failed to register struct '{}'", self.name),
108 }
109 }
110}
111
112impl ASTRegApply for RemoveStructMutation {
113 fn apply_to_registry(&self, ctx: &mut ASTMutationContext) -> MutationResult {
114 let struct_id = self.struct_id;
116
117 if ctx.symbol_registry.kind(struct_id) != Some(SymbolKind::Struct) {
119 return MutationResult {
120 mutation_type: "RemoveStruct".to_string(),
121 changes: 0,
122 description: format!("Symbol {} is not a struct", struct_id),
123 };
124 }
125
126 ctx.ast_registry.remove(struct_id);
127
128 MutationResult {
129 mutation_type: "RemoveStruct".to_string(),
130 changes: 1,
131 description: format!("Removed struct {}", struct_id),
132 }
133 }
134}