ryo-mutations 0.1.0

[experimental] Code transformation primitives for Rust source code
Documentation
//! ReplaceExprAtMutation: Replace expression at a specific position
//!
//! Unlike `ReplaceExprMutation` which uses pattern matching, this mutation
//! replaces an expression at an exact position specified by function SymbolId
//! and body indices.
//!
//! # Example
//! Function `example` at body indices `[0, 1, 2]` targets:
//! `body.stmts[0].expr.child[1].child[2]`

use ryo_source::pure::PureExpr;
use ryo_symbol::SymbolId;

use crate::Mutation;

/// Replace an expression at a specific position using index-based navigation
#[derive(Debug, Clone)]
pub struct ReplaceExprAtMutation {
    /// The target function SymbolId
    pub target_fn: SymbolId,
    /// Body indices for navigation (e.g., [0, 1, 2] for stmts[0].child[1].child[2])
    pub body_indices: Vec<usize>,
    /// The replacement expression
    pub new_expr: PureExpr,
}

impl ReplaceExprAtMutation {
    /// Create a new position-based replacement mutation
    pub fn new(target_fn: SymbolId, body_indices: Vec<usize>, new_expr: PureExpr) -> Self {
        Self {
            target_fn,
            body_indices,
            new_expr,
        }
    }
}

impl Mutation for ReplaceExprAtMutation {
    fn describe(&self) -> String {
        format!(
            "Replace expression at {}::$body::{}",
            self.target_fn,
            self.body_indices
                .iter()
                .map(|i| i.to_string())
                .collect::<Vec<_>>()
                .join("::")
        )
    }

    fn mutation_type(&self) -> &'static str {
        "ReplaceExprAt"
    }

    fn box_clone(&self) -> Box<dyn Mutation> {
        Box::new(self.clone())
    }
}