Skip to main content

ryo_executor/engine/impls/
enum_def.rs

1//! ASTRegApply implementation for enum mutations
2
3use ryo_mutations::basic::{AddEnumMutation, RemoveEnumMutation};
4use ryo_mutations::MutationResult;
5use ryo_source::pure::{
6    PureAttrMeta, PureAttribute, PureEnum, PureGenerics, PureItem, PureVariant, PureVis,
7};
8use ryo_symbol::SymbolKind;
9
10use crate::engine::{ASTMutationContext, ASTRegApply};
11
12impl ASTRegApply for AddEnumMutation {
13    fn apply_to_registry(&self, ctx: &mut ASTMutationContext) -> MutationResult {
14        // Use the provided symbol_id as the parent module
15        let module_id = self.parent;
16
17        // Verify the target is a module
18        if ctx.symbol_registry.kind(module_id) != Some(SymbolKind::Mod) {
19            return MutationResult {
20                mutation_type: "AddEnum".to_string(),
21                changes: 0,
22                description: format!("Target symbol {:?} is not a module", module_id),
23            };
24        }
25
26        // Check if enum already exists in this module
27        let parent_path = match ctx.symbol_registry.path(module_id) {
28            Some(p) => p,
29            None => {
30                return MutationResult {
31                    mutation_type: "AddEnum".to_string(),
32                    changes: 0,
33                    description: format!("Module {:?} not found in registry", module_id),
34                };
35            }
36        };
37
38        let exists = ctx
39            .symbol_registry
40            .iter()
41            .filter(|(id, _)| ctx.symbol_registry.kind(*id) == Some(SymbolKind::Enum))
42            .any(|(_, path)| {
43                path.parent().as_ref() == Some(parent_path) && path.name() == self.name
44            });
45
46        if exists {
47            return MutationResult {
48                mutation_type: "AddEnum".to_string(),
49                changes: 0,
50                description: format!("Enum '{}' already exists in module", self.name),
51            };
52        }
53
54        // Create derive attributes
55        let attrs = if !self.derives.is_empty() {
56            vec![PureAttribute {
57                path: "derive".to_string(),
58                meta: PureAttrMeta::List(self.derives.join(", ")),
59                is_inner: false,
60            }]
61        } else {
62            vec![]
63        };
64
65        // Create variants
66        let variants: Vec<PureVariant> = self
67            .variants
68            .iter()
69            .map(|(name, fields)| PureVariant {
70                attrs: vec![],
71                name: name.clone(),
72                fields: fields.clone(),
73                discriminant: None,
74            })
75            .collect();
76
77        let enum_item = PureEnum {
78            attrs,
79            vis: if self.is_pub {
80                PureVis::Public
81            } else {
82                PureVis::Private
83            },
84            name: self.name.clone(),
85            generics: PureGenerics::default(),
86            variants,
87        };
88
89        // Register the new enum
90        let enum_path = match parent_path.child(&self.name) {
91            Ok(p) => p,
92            Err(_) => {
93                return MutationResult {
94                    mutation_type: "AddEnum".to_string(),
95                    changes: 0,
96                    description: format!("Failed to create path for enum '{}'", self.name),
97                };
98            }
99        };
100
101        match ctx.symbol_registry.register(enum_path, SymbolKind::Enum) {
102            Ok(enum_id) => {
103                ctx.ast_registry.set(enum_id, PureItem::Enum(enum_item));
104                MutationResult {
105                    mutation_type: "AddEnum".to_string(),
106                    changes: 1,
107                    description: format!("Added enum '{}' to module {:?}", self.name, module_id),
108                }
109            }
110            Err(e) => MutationResult {
111                mutation_type: "AddEnum".to_string(),
112                changes: 0,
113                description: format!("Failed to register enum '{}': {:?}", self.name, e),
114            },
115        }
116    }
117}
118
119impl ASTRegApply for RemoveEnumMutation {
120    fn apply_to_registry(&self, ctx: &mut ASTMutationContext) -> MutationResult {
121        // Use the provided symbol_id directly
122        let enum_id = self.symbol_id;
123
124        // Verify the target is an enum
125        if ctx.symbol_registry.kind(enum_id) != Some(SymbolKind::Enum) {
126            return MutationResult {
127                mutation_type: "RemoveEnum".to_string(),
128                changes: 0,
129                description: format!("Symbol {:?} is not an enum", enum_id),
130            };
131        }
132
133        // Remove from AST registry
134        ctx.ast_registry.remove(enum_id);
135
136        MutationResult {
137            mutation_type: "RemoveEnum".to_string(),
138            changes: 1,
139            description: format!("Removed enum {:?}", enum_id),
140        }
141    }
142}