rust_to_dtr 0.16.0

Convert Rust Soroban contracts to DTR format.
Documentation
use crate::Instruction;

pub fn apply(instructions: Vec<Instruction>) -> Vec<Instruction> {
    instructions
        .into_iter()
        .map(|instruction| {
            if instruction.name.ends_with("_and_assign") {
                transform_and_assign_to_normal_op_with_assign(&instruction)
            } else {
                instruction
            }
        })
        .collect()
}

pub fn transform_and_assign_to_normal_op_with_assign(instruction: &Instruction) -> Instruction {
    let operator = instruction.name.clone();
    let left_hand_side = instruction.input[0].clone();
    let right_hand_side = instruction.input[1].clone();

    Instruction::new(
        instruction.id,
        operator.replace("_and_assign", ""),
        vec![left_hand_side.clone(), right_hand_side],
        left_hand_side,
        instruction.scope,
    )
}

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

    #[test]
    fn transform_and_assign_to_normal_op_with_assign_transforms_add_and_assign() {
        let instruction = create_instruction("add_and_assign", vec!["a", "b"], "a");

        let result = transform_and_assign_to_normal_op_with_assign(&instruction);

        assert_eq!(result.name, "add");
        assert_eq!(result.input, vec!["a", "b"]);
        assert_eq!(result.assign, "a");
    }

    #[test]
    fn transform_and_assign_to_normal_op_with_assign_does_not_change_normal_op() {
        let instruction = create_instruction("add", vec!["a", "b"], "a");

        let result = transform_and_assign_to_normal_op_with_assign(&instruction);

        assert_eq!(result.name, "add");
        assert_eq!(result.input, vec!["a", "b"]);
        assert_eq!(result.assign, "a");
    }

    #[test]
    fn transform_and_assign_to_normal_op_with_assign_transforms_subtract_and_assign() {
        let instruction = create_instruction("subtract_and_assign", vec!["a", "b"], "a");

        let result = transform_and_assign_to_normal_op_with_assign(&instruction);

        assert_eq!(result.name, "subtract");
        assert_eq!(result.input, vec!["a", "b"]);
        assert_eq!(result.assign, "a");
    }
}