ryo-mutations 0.1.0

[experimental] Code transformation primitives for Rust source code
Documentation
//! Field mutations: AddFieldMutation, RemoveFieldMutation, AddStructLiteralFieldMutation, RemoveStructLiteralFieldMutation

use ryo_symbol::SymbolId;

use crate::Mutation;

/// Add a field to an existing struct
#[derive(Debug, Clone)]
pub struct AddFieldMutation {
    pub struct_id: SymbolId,
    pub field_name: String,
    pub field_type: String,
    pub is_pub: bool,
}

impl AddFieldMutation {
    pub fn new(
        struct_id: SymbolId,
        field_name: impl Into<String>,
        field_type: impl Into<String>,
    ) -> Self {
        Self {
            struct_id,
            field_name: field_name.into(),
            field_type: field_type.into(),
            is_pub: false,
        }
    }

    pub fn public(mut self) -> Self {
        self.is_pub = true;
        self
    }
}

impl Mutation for AddFieldMutation {
    fn describe(&self) -> String {
        let vis = if self.is_pub { "pub " } else { "" };
        format!(
            "Add {}{}: {} to struct {}",
            vis, self.field_name, self.field_type, self.struct_id
        )
    }

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

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

/// Remove a field from a struct
#[derive(Debug, Clone)]
pub struct RemoveFieldMutation {
    /// SymbolId for the target struct (required, O(1) access)
    pub struct_id: SymbolId,
    pub field_name: String,
}

impl RemoveFieldMutation {
    pub fn new(struct_id: SymbolId, field_name: impl Into<String>) -> Self {
        Self {
            struct_id,
            field_name: field_name.into(),
        }
    }
}

impl Mutation for RemoveFieldMutation {
    fn describe(&self) -> String {
        format!("Remove field '{}' from {}", self.field_name, self.struct_id)
    }

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

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

/// Add a field to all struct literals of a given struct type
#[derive(Debug, Clone)]
pub struct AddStructLiteralFieldMutation {
    /// SymbolId of the struct definition (required, O(1) lookup)
    pub struct_id: SymbolId,
    /// The field name to add
    pub field_name: String,
    /// The value expression (e.g., "None", "Default::default()")
    pub value: String,
}

impl AddStructLiteralFieldMutation {
    pub fn new(
        struct_id: SymbolId,
        field_name: impl Into<String>,
        value: impl Into<String>,
    ) -> Self {
        Self {
            struct_id,
            field_name: field_name.into(),
            value: value.into(),
        }
    }
}

impl Mutation for AddStructLiteralFieldMutation {
    fn describe(&self) -> String {
        format!(
            "Add field '{}' = {} to struct literals ({})",
            self.field_name, self.value, self.struct_id
        )
    }

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

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

/// Remove a field from all struct literals of a given struct type
#[derive(Debug, Clone)]
pub struct RemoveStructLiteralFieldMutation {
    /// SymbolId of the struct definition (required, O(1) lookup)
    pub struct_id: SymbolId,
    /// The field name to remove
    pub field_name: String,
}

impl RemoveStructLiteralFieldMutation {
    pub fn new(struct_id: SymbolId, field_name: impl Into<String>) -> Self {
        Self {
            struct_id,
            field_name: field_name.into(),
        }
    }
}

impl Mutation for RemoveStructLiteralFieldMutation {
    fn describe(&self) -> String {
        format!(
            "Remove field '{}' from struct literals ({})",
            self.field_name, self.struct_id
        )
    }

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

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