ryo-executor 0.1.0

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

use ryo_mutations::basic::{AddFieldMutation, RemoveFieldMutation};
use ryo_mutations::MutationResult;
use ryo_source::pure::{PureField, PureFields, PureItem, PureType, PureVis};

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

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

        // Get the AST
        let ast = match ctx.get_ast_mut(target_id) {
            Some(ast) => ast,
            None => {
                return MutationResult {
                    mutation_type: "AddField".to_string(),
                    changes: 0,
                    description: format!("AST not found for {:?}", target_id),
                };
            }
        };

        // Modify the struct
        if let PureItem::Struct(s) = ast {
            // Check if field already exists
            if let PureFields::Named(fields) = &s.fields {
                if fields.iter().any(|f| f.name == self.field_name) {
                    return MutationResult {
                        mutation_type: "AddField".to_string(),
                        changes: 0,
                        description: format!("Field '{}' already exists", self.field_name),
                    };
                }
            }

            // Create new field
            let new_field = PureField {
                attrs: Vec::new(),
                vis: if self.is_pub {
                    PureVis::Public
                } else {
                    PureVis::Private
                },
                name: self.field_name.clone(),
                ty: PureType::Path(self.field_type.clone()),
            };

            // Add the field
            match &mut s.fields {
                PureFields::Named(fields) => {
                    fields.push(new_field);
                }
                PureFields::Unit => {
                    s.fields = PureFields::Named(vec![new_field]);
                }
                PureFields::Tuple(_) => {
                    return MutationResult {
                        mutation_type: "AddField".to_string(),
                        changes: 0,
                        description: "Cannot add named field to tuple struct".to_string(),
                    };
                }
            }

            ctx.emit_modified(
                target_id,
                ModificationType::FieldAdded(self.field_name.clone()),
            );

            MutationResult {
                mutation_type: "AddField".to_string(),
                changes: 1,
                description: format!("Added field '{}'", self.field_name),
            }
        } else {
            MutationResult {
                mutation_type: "AddField".to_string(),
                changes: 0,
                description: format!("{:?} is not a struct", target_id),
            }
        }
    }
}

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

        // Get the AST
        let ast = match ctx.get_ast_mut(target_id) {
            Some(ast) => ast,
            None => {
                return MutationResult {
                    mutation_type: "RemoveField".to_string(),
                    changes: 0,
                    description: format!("AST not found for {:?}", target_id),
                };
            }
        };

        // Modify the struct
        if let PureItem::Struct(s) = ast {
            if let PureFields::Named(fields) = &mut s.fields {
                let original_len = fields.len();
                fields.retain(|f| f.name != self.field_name);

                if fields.len() < original_len {
                    ctx.emit_modified(
                        target_id,
                        ModificationType::FieldRemoved(self.field_name.clone()),
                    );

                    return MutationResult {
                        mutation_type: "RemoveField".to_string(),
                        changes: 1,
                        description: format!("Removed field '{}'", self.field_name),
                    };
                }
            }

            MutationResult {
                mutation_type: "RemoveField".to_string(),
                changes: 0,
                description: format!("Field '{}' not found", self.field_name),
            }
        } else {
            MutationResult {
                mutation_type: "RemoveField".to_string(),
                changes: 0,
                description: format!("{:?} is not a struct", target_id),
            }
        }
    }
}