Skip to main content

ryo_executor/executor/registry/converters/
derive.rs

1//! DeriveConverter: Converts MutationSpec::AddDerive and RemoveDerive
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::{AddDeriveMutation, RemoveDeriveMutation};
9
10/// Converter for Derive mutations (AddDerive, RemoveDerive)
11#[derive(Debug, Clone, Default)]
12pub struct DeriveConverter;
13
14impl DeriveConverter {
15    pub fn new() -> Self {
16        Self
17    }
18}
19
20// DeriveConverter uses the default implementation of ResolveTargetSymbol
21impl ResolveTargetSymbol for DeriveConverter {}
22
23impl MutationConverter for DeriveConverter {
24    fn spec_kinds(&self) -> &'static [&'static str] {
25        &["AddDerive", "RemoveDerive"]
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::AddDerive {
35                target: target_symbol,
36                derives,
37            } => {
38                // Resolve target_symbol to SymbolId
39                let symbol_id = self.resolve_target_symbol(target_symbol, ctx)?;
40                let mutation = AddDeriveMutation::new(symbol_id, derives.clone());
41                Ok(vec![Box::new(mutation)])
42            }
43            MutationSpec::RemoveDerive {
44                target: target_symbol,
45                derives,
46            } => {
47                // Resolve target_symbol to SymbolId
48                let symbol_id = self.resolve_target_symbol(target_symbol, ctx)?;
49                let mutation = RemoveDeriveMutation::new(symbol_id, derives.clone());
50                Ok(vec![Box::new(mutation)])
51            }
52            _ => Err(ConvertError::TypeMismatch {
53                expected: "AddDerive or RemoveDerive",
54                actual: spec.kind_name().to_string(),
55            }),
56        }
57    }
58}
59
60#[cfg(test)]
61mod tests {
62    use super::*;
63
64    #[test]
65    fn test_derive_converter_spec_kinds() {
66        let converter = DeriveConverter::new();
67        assert_eq!(converter.spec_kinds(), &["AddDerive", "RemoveDerive"]);
68    }
69}