Skip to main content

ryo_executor/executor/registry/converters/
visibility.rs

1//! VisibilityConverter: Converts MutationSpec::ChangeVisibility
2
3use crate::engine::ASTRegApply;
4use crate::executor::registry::converters::ResolveTargetSymbol;
5use crate::executor::registry::{ConvertError, MutationConverter};
6use crate::executor::spec::{MutationSpec, Visibility};
7use ryo_analysis::AnalysisContext;
8use ryo_mutations::ChangeVisibilityMutation;
9use ryo_source::pure::PureVis;
10
11/// Converter for ChangeVisibility mutations
12#[derive(Debug, Clone, Default)]
13pub struct VisibilityConverter;
14
15impl VisibilityConverter {
16    pub fn new() -> Self {
17        Self
18    }
19
20    /// Convert spec Visibility to PureVis
21    fn to_pure_vis(visibility: &Visibility) -> PureVis {
22        match visibility {
23            Visibility::Private => PureVis::Private,
24            Visibility::Pub => PureVis::Public,
25            Visibility::PubCrate => PureVis::Crate,
26            Visibility::PubSuper => PureVis::Super,
27            Visibility::PubIn(_) => PureVis::Public, // Simplified for now
28        }
29    }
30}
31
32// VisibilityConverter uses the default implementation of ResolveTargetSymbol
33impl ResolveTargetSymbol for VisibilityConverter {}
34
35impl MutationConverter for VisibilityConverter {
36    fn spec_kinds(&self) -> &'static [&'static str] {
37        &["ChangeVisibility"]
38    }
39
40    fn convert_v2(
41        &self,
42        spec: &MutationSpec,
43        ctx: &AnalysisContext,
44    ) -> Result<Vec<Box<dyn ASTRegApply>>, ConvertError> {
45        match spec {
46            MutationSpec::ChangeVisibility {
47                target: target_symbol,
48                visibility,
49            } => {
50                // Resolve target_symbol to SymbolId
51                let symbol_id = self.resolve_target_symbol(target_symbol, ctx)?;
52                let pure_vis = Self::to_pure_vis(visibility);
53                let mutation = ChangeVisibilityMutation::new(symbol_id, pure_vis);
54                Ok(vec![Box::new(mutation)])
55            }
56            _ => Err(ConvertError::TypeMismatch {
57                expected: "ChangeVisibility",
58                actual: spec.kind_name().to_string(),
59            }),
60        }
61    }
62}
63
64#[cfg(test)]
65mod tests {
66    use super::*;
67
68    #[test]
69    fn test_visibility_converter_spec_kinds() {
70        let converter = VisibilityConverter::new();
71        assert_eq!(converter.spec_kinds(), &["ChangeVisibility"]);
72    }
73
74    #[test]
75    fn test_visibility_to_pure_vis() {
76        assert!(matches!(
77            VisibilityConverter::to_pure_vis(&Visibility::Private),
78            PureVis::Private
79        ));
80        assert!(matches!(
81            VisibilityConverter::to_pure_vis(&Visibility::Pub),
82            PureVis::Public
83        ));
84        assert!(matches!(
85            VisibilityConverter::to_pure_vis(&Visibility::PubCrate),
86            PureVis::Crate
87        ));
88    }
89}