Skip to main content

ryo_executor/engine/
events.rs

1//! Mutation events for logging and tracking
2//!
3//! Events are emitted during mutation execution and can be used for:
4//! - Logging what changes were made
5//! - UI updates (showing progress)
6//! - Audit trails
7//! - Future: Undo support
8
9use ryo_analysis::{SymbolId, SymbolKind, SymbolPath};
10
11/// Events emitted during mutation execution
12#[derive(Debug, Clone)]
13pub enum MutationEvent {
14    /// New symbol added to registry
15    SymbolAdded { path: SymbolPath, kind: SymbolKind },
16
17    /// Symbol removed from registry
18    SymbolRemoved { path: SymbolPath },
19
20    /// Symbol content modified
21    SymbolModified {
22        id: SymbolId,
23        modification: ModificationType,
24    },
25
26    /// Symbol renamed (path changed)
27    SymbolRenamed {
28        old_path: SymbolPath,
29        new_path: Box<SymbolPath>,
30    },
31}
32
33/// Type of modification made to a symbol
34#[derive(Debug, Clone)]
35pub enum ModificationType {
36    /// Field added to struct
37    FieldAdded(String),
38    /// Field removed from struct
39    FieldRemoved(String),
40    /// Method added to impl block
41    MethodAdded(String),
42    /// Method removed from impl block
43    MethodRemoved(String),
44    /// Variant added to enum
45    VariantAdded(String),
46    /// Variant removed from enum
47    VariantRemoved(String),
48    /// Visibility changed
49    VisibilityChanged,
50    /// Derive macro added
51    DeriveAdded(String),
52    /// Derive macro removed
53    DeriveRemoved(String),
54    /// Function/method body modified
55    BodyModified,
56    /// Type signature changed
57    TypeChanged,
58    /// Attribute added
59    AttributeAdded(String),
60    /// Attribute removed
61    AttributeRemoved(String),
62    /// Other modification (describe in string)
63    Other(String),
64}
65
66impl std::fmt::Display for MutationEvent {
67    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
68        match self {
69            MutationEvent::SymbolAdded { path, kind } => {
70                write!(f, "Added {:?} {}", kind, path)
71            }
72            MutationEvent::SymbolRemoved { path } => {
73                write!(f, "Removed {}", path)
74            }
75            MutationEvent::SymbolModified { id, modification } => {
76                write!(f, "Modified {:?}: {}", id, modification)
77            }
78            MutationEvent::SymbolRenamed { old_path, new_path } => {
79                write!(f, "Renamed {} -> {}", old_path, new_path)
80            }
81        }
82    }
83}
84
85impl std::fmt::Display for ModificationType {
86    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
87        match self {
88            ModificationType::FieldAdded(name) => write!(f, "field added: {}", name),
89            ModificationType::FieldRemoved(name) => write!(f, "field removed: {}", name),
90            ModificationType::MethodAdded(name) => write!(f, "method added: {}", name),
91            ModificationType::MethodRemoved(name) => write!(f, "method removed: {}", name),
92            ModificationType::VariantAdded(name) => write!(f, "variant added: {}", name),
93            ModificationType::VariantRemoved(name) => write!(f, "variant removed: {}", name),
94            ModificationType::VisibilityChanged => write!(f, "visibility changed"),
95            ModificationType::DeriveAdded(name) => write!(f, "derive added: {}", name),
96            ModificationType::DeriveRemoved(name) => write!(f, "derive removed: {}", name),
97            ModificationType::BodyModified => write!(f, "body modified"),
98            ModificationType::TypeChanged => write!(f, "type changed"),
99            ModificationType::AttributeAdded(attr) => write!(f, "attribute added: {}", attr),
100            ModificationType::AttributeRemoved(attr) => write!(f, "attribute removed: {}", attr),
101            ModificationType::Other(desc) => write!(f, "{}", desc),
102        }
103    }
104}
105
106// ============================================================================
107// Event analysis for incremental updates
108// ============================================================================
109
110use ryo_analysis::SymbolRegistry;
111
112/// Extract affected symbol IDs from mutation events.
113///
114/// Returns IDs of symbols that were modified, added, or renamed.
115/// These IDs are used to trigger incremental graph updates.
116pub fn collect_affected_ids(events: &[MutationEvent], registry: &SymbolRegistry) -> Vec<SymbolId> {
117    let mut ids = Vec::new();
118
119    for event in events {
120        match event {
121            MutationEvent::SymbolAdded { path, .. } => {
122                // Newly added symbol - look up the ID that was just registered
123                if let Some(id) = registry.lookup(path) {
124                    ids.push(id);
125                }
126            }
127            MutationEvent::SymbolRemoved { path } => {
128                // Symbol being removed - we need its ID for edge cleanup
129                if let Some(id) = registry.lookup(path) {
130                    ids.push(id);
131                }
132            }
133            MutationEvent::SymbolModified { id, .. } => {
134                // Modified symbol - needs edge rebuilding
135                ids.push(*id);
136            }
137            MutationEvent::SymbolRenamed { new_path, .. } => {
138                // Renamed symbol - look up by new path
139                if let Some(id) = registry.lookup(new_path) {
140                    ids.push(id);
141                }
142            }
143        }
144    }
145
146    // Deduplicate
147    ids.sort_unstable();
148    ids.dedup();
149    ids
150}