ryo-executor 0.1.0

[experimental] Mutation execution engine for RYO - parallel execution, conflict detection, workspace management
Documentation
//! Mutation events for logging and tracking
//!
//! Events are emitted during mutation execution and can be used for:
//! - Logging what changes were made
//! - UI updates (showing progress)
//! - Audit trails
//! - Future: Undo support

use ryo_analysis::{SymbolId, SymbolKind, SymbolPath};

/// Events emitted during mutation execution
#[derive(Debug, Clone)]
pub enum MutationEvent {
    /// New symbol added to registry
    SymbolAdded { path: SymbolPath, kind: SymbolKind },

    /// Symbol removed from registry
    SymbolRemoved { path: SymbolPath },

    /// Symbol content modified
    SymbolModified {
        id: SymbolId,
        modification: ModificationType,
    },

    /// Symbol renamed (path changed)
    SymbolRenamed {
        old_path: SymbolPath,
        new_path: Box<SymbolPath>,
    },
}

/// Type of modification made to a symbol
#[derive(Debug, Clone)]
pub enum ModificationType {
    /// Field added to struct
    FieldAdded(String),
    /// Field removed from struct
    FieldRemoved(String),
    /// Method added to impl block
    MethodAdded(String),
    /// Method removed from impl block
    MethodRemoved(String),
    /// Variant added to enum
    VariantAdded(String),
    /// Variant removed from enum
    VariantRemoved(String),
    /// Visibility changed
    VisibilityChanged,
    /// Derive macro added
    DeriveAdded(String),
    /// Derive macro removed
    DeriveRemoved(String),
    /// Function/method body modified
    BodyModified,
    /// Type signature changed
    TypeChanged,
    /// Attribute added
    AttributeAdded(String),
    /// Attribute removed
    AttributeRemoved(String),
    /// Other modification (describe in string)
    Other(String),
}

impl std::fmt::Display for MutationEvent {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            MutationEvent::SymbolAdded { path, kind } => {
                write!(f, "Added {:?} {}", kind, path)
            }
            MutationEvent::SymbolRemoved { path } => {
                write!(f, "Removed {}", path)
            }
            MutationEvent::SymbolModified { id, modification } => {
                write!(f, "Modified {:?}: {}", id, modification)
            }
            MutationEvent::SymbolRenamed { old_path, new_path } => {
                write!(f, "Renamed {} -> {}", old_path, new_path)
            }
        }
    }
}

impl std::fmt::Display for ModificationType {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            ModificationType::FieldAdded(name) => write!(f, "field added: {}", name),
            ModificationType::FieldRemoved(name) => write!(f, "field removed: {}", name),
            ModificationType::MethodAdded(name) => write!(f, "method added: {}", name),
            ModificationType::MethodRemoved(name) => write!(f, "method removed: {}", name),
            ModificationType::VariantAdded(name) => write!(f, "variant added: {}", name),
            ModificationType::VariantRemoved(name) => write!(f, "variant removed: {}", name),
            ModificationType::VisibilityChanged => write!(f, "visibility changed"),
            ModificationType::DeriveAdded(name) => write!(f, "derive added: {}", name),
            ModificationType::DeriveRemoved(name) => write!(f, "derive removed: {}", name),
            ModificationType::BodyModified => write!(f, "body modified"),
            ModificationType::TypeChanged => write!(f, "type changed"),
            ModificationType::AttributeAdded(attr) => write!(f, "attribute added: {}", attr),
            ModificationType::AttributeRemoved(attr) => write!(f, "attribute removed: {}", attr),
            ModificationType::Other(desc) => write!(f, "{}", desc),
        }
    }
}

// ============================================================================
// Event analysis for incremental updates
// ============================================================================

use ryo_analysis::SymbolRegistry;

/// Extract affected symbol IDs from mutation events.
///
/// Returns IDs of symbols that were modified, added, or renamed.
/// These IDs are used to trigger incremental graph updates.
pub fn collect_affected_ids(events: &[MutationEvent], registry: &SymbolRegistry) -> Vec<SymbolId> {
    let mut ids = Vec::new();

    for event in events {
        match event {
            MutationEvent::SymbolAdded { path, .. } => {
                // Newly added symbol - look up the ID that was just registered
                if let Some(id) = registry.lookup(path) {
                    ids.push(id);
                }
            }
            MutationEvent::SymbolRemoved { path } => {
                // Symbol being removed - we need its ID for edge cleanup
                if let Some(id) = registry.lookup(path) {
                    ids.push(id);
                }
            }
            MutationEvent::SymbolModified { id, .. } => {
                // Modified symbol - needs edge rebuilding
                ids.push(*id);
            }
            MutationEvent::SymbolRenamed { new_path, .. } => {
                // Renamed symbol - look up by new path
                if let Some(id) = registry.lookup(new_path) {
                    ids.push(id);
                }
            }
        }
    }

    // Deduplicate
    ids.sort_unstable();
    ids.dedup();
    ids
}