#[cfg(test)]
mod tests {
#[test]
fn test_struct_definition_simple() {
let c_code = r#"
struct Point {
int x;
int y;
};
"#;
let rust_expected = r#"
struct Point {
x: i32,
y: i32,
}
"#;
assert!(c_code.contains("struct Point"));
assert!(rust_expected.contains("struct Point"));
assert!(c_code.contains("int x;"));
assert!(rust_expected.contains("x: i32,"));
}
#[test]
fn test_struct_definition_multiple_types() {
let c_code = r#"
struct Person {
char name[50];
int age;
float height;
double weight;
};
"#;
let rust_expected = r#"
struct Person {
name: [u8; 50],
age: i32,
height: f32,
weight: f64,
}
"#;
assert!(c_code.contains("struct Person"));
assert!(rust_expected.contains("struct Person"));
assert!(c_code.contains("char name[50]"));
assert!(rust_expected.contains("name: [u8; 50]"));
}
#[test]
fn test_struct_definition_typedef() {
let c_code = r#"
typedef struct {
int x;
int y;
} Point;
"#;
let rust_expected = r#"
struct Point {
x: i32,
y: i32,
}
"#;
assert!(c_code.contains("typedef struct"));
assert!(rust_expected.contains("struct Point"));
}
#[test]
fn test_struct_definition_typedef_with_tag() {
let c_code = r#"
typedef struct Point {
int x;
int y;
} Point;
"#;
let rust_expected = r#"
struct Point {
x: i32,
y: i32,
}
"#;
assert!(c_code.contains("typedef struct Point"));
assert!(rust_expected.contains("struct Point"));
}
#[test]
fn test_struct_initialization() {
let c_code = r#"
struct Point {
int x;
int y;
};
struct Point p = { 10, 20 };
"#;
let rust_expected = r#"
struct Point {
x: i32,
y: i32,
}
let p = Point { x: 10, y: 20 };
"#;
assert!(c_code.contains("struct Point p = { 10, 20 }"));
assert!(rust_expected.contains("let p = Point { x: 10, y: 20 }"));
}
#[test]
fn test_struct_member_access() {
let c_code = r#"
struct Point p;
p.x = 10;
int y = p.y;
"#;
let rust_expected = r#"
let mut p: Point;
p.x = 10;
let y = p.y;
"#;
assert!(c_code.contains("p.x = 10"));
assert!(rust_expected.contains("p.x = 10"));
}
#[test]
fn test_struct_pointer_access() {
let c_code = r#"
struct Point* ptr;
ptr->x = 10;
int y = ptr->y;
"#;
let rust_expected = r#"
let ptr: &mut Point;
ptr.x = 10;
let y = ptr.y;
"#;
assert!(c_code.contains("ptr->x"));
assert!(rust_expected.contains("ptr.x"));
}
#[test]
fn test_struct_with_pointer_fields() {
let c_code = r#"
struct Node {
int data;
struct Node* next;
};
"#;
let rust_expected = r#"
struct Node {
data: i32,
next: Option<Box<Node>>,
}
"#;
assert!(c_code.contains("struct Node* next"));
assert!(rust_expected.contains("next: Option<Box<Node>>"));
}
#[test]
fn test_struct_empty() {
let c_code = r#"
struct Empty {
};
"#;
let rust_expected = r#"
struct Empty {}
"#;
assert!(c_code.contains("struct Empty"));
assert!(rust_expected.contains("struct Empty"));
}
#[test]
fn test_struct_with_arrays() {
let c_code = r#"
struct Matrix {
int data[10][10];
int rows;
int cols;
};
"#;
let rust_expected = r#"
struct Matrix {
data: [[i32; 10]; 10],
rows: i32,
cols: i32,
}
"#;
assert!(c_code.contains("int data[10][10]"));
assert!(rust_expected.contains("data: [[i32; 10]; 10]"));
}
#[test]
fn test_struct_function_parameter() {
let c_code = r#"
void process(struct Point p) {
printf("%d, %d\n", p.x, p.y);
}
"#;
let rust_expected = r#"
fn process(p: Point) {
println!("{}, {}", p.x, p.y);
}
"#;
assert!(c_code.contains("struct Point p"));
assert!(rust_expected.contains("p: Point"));
}
#[test]
fn test_struct_pointer_parameter() {
let c_code = r#"
void process(struct Point* p) {
printf("%d, %d\n", p->x, p->y);
}
"#;
let rust_expected = r#"
fn process(p: &Point) {
println!("{}, {}", p.x, p.y);
}
"#;
assert!(c_code.contains("struct Point* p"));
assert!(rust_expected.contains("p: &Point"));
assert!(c_code.contains("p->x"));
assert!(rust_expected.contains("p.x"));
}
#[test]
fn test_struct_designated_initializers() {
let c_code = r#"
struct Point p = { .x = 10, .y = 20 };
"#;
let rust_expected = r#"
let p = Point { x: 10, y: 20 };
"#;
assert!(c_code.contains(".x = 10"));
assert!(rust_expected.contains("x: 10"));
}
#[test]
fn test_struct_partial_initialization() {
let c_code = r#"
struct Point p = { .x = 10 }; // y initialized to 0
"#;
let rust_expected = r#"
let p = Point { x: 10, ..Default::default() }; // y from Default
"#;
assert!(c_code.contains(".x = 10"));
assert!(rust_expected.contains("..Default::default()"));
}
#[test]
fn test_struct_with_function_pointer() {
let c_code = r#"
struct Handler {
void (*callback)(int);
int data;
};
"#;
let rust_expected = r#"
struct Handler {
callback: fn(i32),
data: i32,
}
"#;
assert!(c_code.contains("void (*callback)(int)"));
assert!(rust_expected.contains("callback: fn(i32)"));
}
#[test]
fn test_struct_with_nested_struct() {
let c_code = r#"
struct Rectangle {
struct Point top_left;
struct Point bottom_right;
};
"#;
let rust_expected = r#"
struct Rectangle {
top_left: Point,
bottom_right: Point,
}
"#;
assert!(c_code.contains("struct Point top_left"));
assert!(rust_expected.contains("top_left: Point"));
}
#[test]
fn test_struct_transformation_summary() {
let c_code = r#"
// Rule 1: Basic definition
struct Point { int x; int y; };
// Rule 2: typedef removed
typedef struct { int x; int y; } Point;
// Rule 3: Initialization
struct Point p = { 10, 20 };
// Rule 4: Member access
p.x = 10;
// Rule 5: Pointer access
ptr->x = 10;
// Rule 6: Self-referential
struct Node { int data; struct Node* next; };
// Rule 7: Function parameter
void f(struct Point p);
// Rule 8: Pointer parameter
void f(struct Point* p);
// Rule 9: Designated initializers
struct Point p = { .x = 10, .y = 20 };
"#;
let rust_expected = r#"
// Rule 1: Same structure, different syntax
struct Point { x: i32, y: i32 }
// Rule 2: No typedef needed
struct Point { x: i32, y: i32 }
// Rule 3: Named fields required
let p = Point { x: 10, y: 20 };
// Rule 4: Same syntax
p.x = 10;
// Rule 5: Auto-deref (no arrow)
ptr.x = 10;
// Rule 6: Option<Box<T>> for nullable
struct Node { data: i32, next: Option<Box<Node>> }
// Rule 7: No 'struct' keyword in type
fn f(p: Point);
// Rule 8: Borrow instead of pointer
fn f(p: &Point);
// Rule 9: Same syntax (always required)
let p = Point { x: 10, y: 20 };
"#;
assert!(c_code.contains("struct Point { int x; int y; }"));
assert!(rust_expected.contains("struct Point { x: i32, y: i32 }"));
assert!(c_code.contains("typedef struct"));
assert!(c_code.contains("ptr->x"));
assert!(rust_expected.contains("ptr.x"));
assert!(c_code.contains("struct Node* next"));
assert!(rust_expected.contains("Option<Box<Node>>"));
}
}