Skip to main content

ryo_executor/executor/registry/converters/
remove.rs

1//! RemoveConverter: Converts MutationSpec::RemoveItem
2
3use crate::engine::ASTRegApply;
4use crate::executor::registry::converters::ResolveTargetSymbol;
5use crate::executor::registry::{ConvertError, MutationConverter};
6use crate::executor::spec::MutationSpec;
7use ryo_analysis::AnalysisContext;
8use ryo_mutations::RemoveItemMutation;
9
10/// Converter for RemoveItem mutations
11#[derive(Debug, Clone, Default)]
12pub struct RemoveConverter;
13
14impl RemoveConverter {
15    pub fn new() -> Self {
16        Self
17    }
18}
19
20// RemoveConverter uses the default implementation of ResolveTargetSymbol
21impl ResolveTargetSymbol for RemoveConverter {}
22
23impl MutationConverter for RemoveConverter {
24    fn spec_kinds(&self) -> &'static [&'static str] {
25        &["RemoveItem"]
26    }
27
28    fn convert_v2(
29        &self,
30        spec: &MutationSpec,
31        ctx: &AnalysisContext,
32    ) -> Result<Vec<Box<dyn ASTRegApply>>, ConvertError> {
33        match spec {
34            MutationSpec::RemoveItem {
35                target: target_symbol,
36                item_kind,
37            } => {
38                // Resolve target_symbol to SymbolId
39                let symbol_id = self.resolve_target_symbol(target_symbol, ctx)?;
40                let mutation = RemoveItemMutation::new(symbol_id, *item_kind);
41                Ok(vec![Box::new(mutation)])
42            }
43            _ => Err(ConvertError::TypeMismatch {
44                expected: "RemoveItem",
45                actual: spec.kind_name().to_string(),
46            }),
47        }
48    }
49}
50
51#[cfg(test)]
52mod tests {
53    use super::*;
54    use ryo_source::ItemKind;
55    use ryo_symbol::SymbolId;
56
57    #[test]
58    fn test_remove_converter_spec_kinds() {
59        let converter = RemoveConverter::new();
60        assert_eq!(converter.spec_kinds(), &["RemoveItem"]);
61    }
62
63    #[test]
64    fn test_remove_converter_can_handle() {
65        let converter = RemoveConverter::new();
66
67        let spec = MutationSpec::RemoveItem {
68            target: crate::executor::spec::MutationTargetSymbol::ById(SymbolId::default()),
69            item_kind: ItemKind::Struct,
70        };
71        assert!(converter.can_handle(&spec));
72    }
73}