ryo-executor 0.1.0

[experimental] Mutation execution engine for RYO - parallel execution, conflict detection, workspace management
Documentation
//! ASTRegApply implementation for variant mutations

use ryo_mutations::basic::{AddVariantMutation, RemoveVariantMutation};
use ryo_mutations::MutationResult;
use ryo_source::pure::{PureItem, PureVariant};

use crate::engine::{ASTMutationContext, ASTRegApply, ModificationType, MutationEvent};

impl ASTRegApply for AddVariantMutation {
    fn apply_to_registry(&self, ctx: &mut ASTMutationContext) -> MutationResult {
        let target_id = self.enum_id;

        // Get the AST for this symbol
        let item = match ctx.ast_registry.get(target_id) {
            Some(item) => item.clone(),
            None => {
                return MutationResult {
                    mutation_type: "AddVariant".to_string(),
                    changes: 0,
                    description: format!("AST not found for {:?}", target_id),
                };
            }
        };

        // Modify the item
        let new_item = match item {
            PureItem::Enum(mut e) => {
                // Check if variant already exists
                if e.variants.iter().any(|v| v.name == self.variant_name) {
                    return MutationResult {
                        mutation_type: "AddVariant".to_string(),
                        changes: 0,
                        description: format!(
                            "Variant '{}' already exists in {:?}",
                            self.variant_name, target_id
                        ),
                    };
                }

                e.variants.push(PureVariant {
                    attrs: Vec::new(),
                    name: self.variant_name.clone(),
                    fields: self.fields.clone(),
                    discriminant: None,
                });
                PureItem::Enum(e)
            }
            _ => {
                return MutationResult {
                    mutation_type: "AddVariant".to_string(),
                    changes: 0,
                    description: format!("{:?} is not an enum", target_id),
                };
            }
        };

        // Update the registry
        ctx.set_ast(target_id, new_item);

        // Emit event
        ctx.emit(MutationEvent::SymbolModified {
            id: target_id,
            modification: ModificationType::VariantAdded(self.variant_name.clone()),
        });

        MutationResult {
            mutation_type: "AddVariant".to_string(),
            changes: 1,
            description: format!("Added variant '{}' to {:?}", self.variant_name, target_id),
        }
    }
}

impl ASTRegApply for RemoveVariantMutation {
    fn apply_to_registry(&self, ctx: &mut ASTMutationContext) -> MutationResult {
        let target_id = self.enum_id;

        // Get the AST for this symbol
        let item = match ctx.ast_registry.get(target_id) {
            Some(item) => item.clone(),
            None => {
                return MutationResult {
                    mutation_type: "RemoveVariant".to_string(),
                    changes: 0,
                    description: format!("AST not found for {:?}", target_id),
                };
            }
        };

        // Modify the item
        let (new_item, removed) = match item {
            PureItem::Enum(mut e) => {
                let original_len = e.variants.len();
                e.variants.retain(|v| v.name != self.variant_name);
                let removed = e.variants.len() < original_len;
                (PureItem::Enum(e), removed)
            }
            _ => {
                return MutationResult {
                    mutation_type: "RemoveVariant".to_string(),
                    changes: 0,
                    description: format!("{:?} is not an enum", target_id),
                };
            }
        };

        if removed {
            // Update the registry
            ctx.set_ast(target_id, new_item);

            // Emit event
            ctx.emit(MutationEvent::SymbolModified {
                id: target_id,
                modification: ModificationType::VariantRemoved(self.variant_name.clone()),
            });
        }

        MutationResult {
            mutation_type: "RemoveVariant".to_string(),
            changes: if removed { 1 } else { 0 },
            description: if removed {
                format!(
                    "Removed variant '{}' from {:?}",
                    self.variant_name, target_id
                )
            } else {
                format!(
                    "Variant '{}' not found in {:?}",
                    self.variant_name, target_id
                )
            },
        }
    }
}