ryo-executor 0.1.0

[experimental] Mutation execution engine for RYO - parallel execution, conflict detection, workspace management
Documentation
//! VisibilityConverter: Converts MutationSpec::ChangeVisibility

use crate::engine::ASTRegApply;
use crate::executor::registry::converters::ResolveTargetSymbol;
use crate::executor::registry::{ConvertError, MutationConverter};
use crate::executor::spec::{MutationSpec, Visibility};
use ryo_analysis::AnalysisContext;
use ryo_mutations::ChangeVisibilityMutation;
use ryo_source::pure::PureVis;

/// Converter for ChangeVisibility mutations
#[derive(Debug, Clone, Default)]
pub struct VisibilityConverter;

impl VisibilityConverter {
    pub fn new() -> Self {
        Self
    }

    /// Convert spec Visibility to PureVis
    fn to_pure_vis(visibility: &Visibility) -> PureVis {
        match visibility {
            Visibility::Private => PureVis::Private,
            Visibility::Pub => PureVis::Public,
            Visibility::PubCrate => PureVis::Crate,
            Visibility::PubSuper => PureVis::Super,
            Visibility::PubIn(_) => PureVis::Public, // Simplified for now
        }
    }
}

// VisibilityConverter uses the default implementation of ResolveTargetSymbol
impl ResolveTargetSymbol for VisibilityConverter {}

impl MutationConverter for VisibilityConverter {
    fn spec_kinds(&self) -> &'static [&'static str] {
        &["ChangeVisibility"]
    }

    fn convert_v2(
        &self,
        spec: &MutationSpec,
        ctx: &AnalysisContext,
    ) -> Result<Vec<Box<dyn ASTRegApply>>, ConvertError> {
        match spec {
            MutationSpec::ChangeVisibility {
                target: target_symbol,
                visibility,
            } => {
                // Resolve target_symbol to SymbolId
                let symbol_id = self.resolve_target_symbol(target_symbol, ctx)?;
                let pure_vis = Self::to_pure_vis(visibility);
                let mutation = ChangeVisibilityMutation::new(symbol_id, pure_vis);
                Ok(vec![Box::new(mutation)])
            }
            _ => Err(ConvertError::TypeMismatch {
                expected: "ChangeVisibility",
                actual: spec.kind_name().to_string(),
            }),
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_visibility_converter_spec_kinds() {
        let converter = VisibilityConverter::new();
        assert_eq!(converter.spec_kinds(), &["ChangeVisibility"]);
    }

    #[test]
    fn test_visibility_to_pure_vis() {
        assert!(matches!(
            VisibilityConverter::to_pure_vis(&Visibility::Private),
            PureVis::Private
        ));
        assert!(matches!(
            VisibilityConverter::to_pure_vis(&Visibility::Pub),
            PureVis::Public
        ));
        assert!(matches!(
            VisibilityConverter::to_pure_vis(&Visibility::PubCrate),
            PureVis::Crate
        ));
    }
}