#[cfg(test)]
mod tests {
#[test]
fn test_simple_array_zero_init() {
let c_code = r#"
int arr[10] = {0};
"#;
let rust_expected = r#"
let arr: [i32; 10] = [0; 10];
"#;
assert!(c_code.contains("[10] = {0}"));
assert!(rust_expected.contains("[0; 10]"));
}
#[test]
fn test_array_with_explicit_values() {
let c_code = r#"
int arr[5] = {1, 2, 3, 4, 5};
"#;
let rust_expected = r#"
let arr: [i32; 5] = [1, 2, 3, 4, 5];
"#;
assert!(c_code.contains("{1, 2, 3, 4, 5}"));
assert!(rust_expected.contains("[1, 2, 3, 4, 5]"));
}
#[test]
fn test_array_access_read() {
let c_code = r#"
int arr[10] = {0};
int val = arr[5];
"#;
let rust_expected = r#"
let arr: [i32; 10] = [0; 10];
let val = arr[5]; // Bounds checked at runtime
"#;
assert!(c_code.contains("arr[5]"));
assert!(rust_expected.contains("arr[5]"));
}
#[test]
fn test_array_modification() {
let c_code = r#"
int arr[10] = {0};
arr[3] = 42;
"#;
let rust_expected = r#"
let mut arr: [i32; 10] = [0; 10];
arr[3] = 42; // Bounds checked
"#;
assert!(c_code.contains("arr[3] = 42"));
assert!(rust_expected.contains("let mut arr"));
assert!(rust_expected.contains("arr[3] = 42"));
}
#[test]
fn test_array_function_parameter() {
let c_code = r#"
void process(int arr[], int len) {
for (int i = 0; i < len; i++) {
arr[i] = i;
}
}
int main() {
int data[10];
process(data, 10); // Size passed separately
}
"#;
let rust_expected = r#"
fn process(arr: &mut [i32]) {
for (i, item) in arr.iter_mut().enumerate() {
*item = i as i32;
}
}
fn main() {
let mut data: [i32; 10] = [0; 10];
process(&mut data); // Size included in slice
}
"#;
assert!(c_code.contains("int arr[]"));
assert!(rust_expected.contains("&mut [i32]"));
}
#[test]
fn test_array_iteration() {
let c_code = r#"
int arr[10] = {0};
for (int i = 0; i < 10; i++) {
arr[i] = i * 2;
}
"#;
let rust_expected = r#"
let mut arr: [i32; 10] = [0; 10];
for i in 0..10 {
arr[i] = i * 2;
}
"#;
assert!(c_code.contains("i < 10"));
assert!(rust_expected.contains("0..10"));
}
#[test]
fn test_multidimensional_array() {
let c_code = r#"
int matrix[3][4] = {0};
matrix[1][2] = 5;
"#;
let rust_expected = r#"
let mut matrix: [[i32; 4]; 3] = [[0; 4]; 3];
matrix[1][2] = 5;
"#;
assert!(c_code.contains("[3][4]"));
assert!(rust_expected.contains("[[i32; 4]; 3]"));
}
#[test]
fn test_array_with_const_size() {
let c_code = r#"
#define SIZE 20
int arr[SIZE] = {0};
"#;
let rust_expected = r#"
const SIZE: usize = 20;
let arr: [i32; SIZE] = [0; SIZE];
"#;
assert!(c_code.contains("SIZE"));
assert!(rust_expected.contains("const SIZE"));
}
#[test]
fn test_array_of_floats() {
let c_code = r#"
float values[5] = {1.0, 2.0, 3.0, 4.0, 5.0};
"#;
let rust_expected = r#"
let values: [f32; 5] = [1.0, 2.0, 3.0, 4.0, 5.0];
"#;
assert!(c_code.contains("float"));
assert!(rust_expected.contains("f32"));
}
#[test]
fn test_array_sum() {
let c_code = r#"
int arr[5] = {1, 2, 3, 4, 5};
int sum = 0;
for (int i = 0; i < 5; i++) {
sum += arr[i];
}
"#;
let rust_loop = r#"
let arr: [i32; 5] = [1, 2, 3, 4, 5];
let mut sum = 0;
for i in 0..5 {
sum += arr[i];
}
"#;
let rust_idiomatic = r#"
let arr: [i32; 5] = [1, 2, 3, 4, 5];
let sum: i32 = arr.iter().sum();
"#;
assert!(c_code.contains("sum += arr[i]"));
assert!(rust_loop.contains("sum += arr[i]"));
assert!(rust_idiomatic.contains(".sum()"));
}
#[test]
fn test_array_search() {
let c_code = r#"
int arr[10] = {1, 5, 3, 7, 2, 8, 4, 6, 9, 0};
int target = 7;
int found = -1;
for (int i = 0; i < 10; i++) {
if (arr[i] == target) {
found = i;
break;
}
}
"#;
let rust_expected = r#"
let arr: [i32; 10] = [1, 5, 3, 7, 2, 8, 4, 6, 9, 0];
let target = 7;
let mut found = -1;
for i in 0..10 {
if arr[i] == target {
found = i as i32;
break;
}
}
"#;
assert!(c_code.contains("if (arr[i] == target)"));
assert!(rust_expected.contains("if arr[i] == target"));
}
#[test]
fn test_array_copy() {
let c_code = r#"
int src[5] = {1, 2, 3, 4, 5};
int dst[5];
for (int i = 0; i < 5; i++) {
dst[i] = src[i];
}
"#;
let rust_loop = r#"
let src: [i32; 5] = [1, 2, 3, 4, 5];
let mut dst: [i32; 5] = [0; 5];
for i in 0..5 {
dst[i] = src[i];
}
"#;
let rust_idiomatic = r#"
let src: [i32; 5] = [1, 2, 3, 4, 5];
let mut dst = src; // Copy trait for arrays
"#;
assert!(c_code.contains("dst[i] = src[i]"));
assert!(rust_loop.contains("dst[i] = src[i]"));
assert!(rust_idiomatic.contains("let mut dst = src"));
}
#[test]
fn test_array_in_struct() {
let c_code = r#"
struct Data {
int values[10];
int count;
};
struct Data data = {{0}, 0};
"#;
let rust_expected = r#"
struct Data {
values: [i32; 10],
count: i32,
}
let data = Data {
values: [0; 10],
count: 0,
};
"#;
assert!(c_code.contains("int values[10]"));
assert!(rust_expected.contains("values: [i32; 10]"));
}
#[test]
fn test_const_array() {
let c_code = r#"
const int lookup[5] = {10, 20, 30, 40, 50};
"#;
let rust_expected = r#"
const LOOKUP: [i32; 5] = [10, 20, 30, 40, 50];
"#;
assert!(c_code.contains("const int"));
assert!(rust_expected.contains("const LOOKUP"));
}
#[test]
fn test_array_transformation_rules_summary() {
let c_code = r#"
// Rule 1: Zero initialization
int arr1[10] = {0};
// Rule 2: Explicit values
int arr2[5] = {1, 2, 3, 4, 5};
// Rule 3: Array access (no bounds check in C!)
int val = arr1[5];
// Rule 4: Array modification
arr1[3] = 42;
// Rule 5: Function parameter (size lost!)
void process(int arr[], int len) { ... }
// Rule 6: Multidimensional
int matrix[3][4] = {0};
"#;
let rust_expected = r#"
// Rule 1: Zero initialization
let arr1: [i32; 10] = [0; 10];
// Rule 2: Explicit values
let arr2: [i32; 5] = [1, 2, 3, 4, 5];
// Rule 3: Array access (bounds checked!)
let val = arr1[5];
// Rule 4: Array modification (needs mut)
arr1[3] = 42;
// Rule 5: Function parameter (size preserved!)
fn process(arr: &[i32]) { ... }
// Rule 6: Multidimensional
let matrix: [[i32; 4]; 3] = [[0; 4]; 3];
"#;
assert!(c_code.contains("int arr"));
assert!(rust_expected.contains("[i32;"));
assert!(c_code.contains("arr[]"));
assert!(rust_expected.contains("&[i32]"));
}
}