#[cfg(test)]
mod tests {
#[test]
fn test_member_access_dot() {
let c_code = r#"
struct Point {
int x;
int y;
};
struct Point p;
p.x = 10;
int y = p.y;
"#;
let rust_expected = r#"
struct Point {
x: i32,
y: i32,
}
let mut p: Point;
p.x = 10;
let y = p.y;
"#;
assert!(c_code.contains("p.x"));
assert!(rust_expected.contains("p.x"));
}
#[test]
fn test_member_access_arrow() {
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_member_access_explicit_deref() {
let c_code = r#"
struct Point* ptr;
(*ptr).x = 10;
"#;
let rust_expected = r#"
let ptr: &mut Point;
ptr.x = 10;
"#;
assert!(c_code.contains("(*ptr).x"));
assert!(rust_expected.contains("ptr.x"));
}
#[test]
fn test_member_access_nested() {
let c_code = r#"
struct Rectangle {
struct Point top_left;
struct Point bottom_right;
};
struct Rectangle rect;
rect.top_left.x = 0;
int y = rect.bottom_right.y;
"#;
let rust_expected = r#"
struct Rectangle {
top_left: Point,
bottom_right: Point,
}
let mut rect: Rectangle;
rect.top_left.x = 0;
let y = rect.bottom_right.y;
"#;
assert!(c_code.contains("rect.top_left.x"));
assert!(rust_expected.contains("rect.top_left.x"));
}
#[test]
fn test_member_access_pointer_nested() {
let c_code = r#"
struct Rectangle* ptr;
ptr->top_left.x = 0;
int y = ptr->bottom_right.y;
"#;
let rust_expected = r#"
let ptr: &mut Rectangle;
ptr.top_left.x = 0;
let y = ptr.bottom_right.y;
"#;
assert!(c_code.contains("ptr->top_left.x"));
assert!(rust_expected.contains("ptr.top_left.x"));
}
#[test]
fn test_member_access_function_arg() {
let c_code = r#"
void process(int value) { }
struct Point p;
process(p.x);
"#;
let rust_expected = r#"
fn process(value: i32) { }
let p: Point;
process(p.x);
"#;
assert!(c_code.contains("process(p.x)"));
assert!(rust_expected.contains("process(p.x)"));
}
#[test]
fn test_member_access_in_expression() {
let c_code = r#"
struct Point p;
int sum = p.x + p.y;
int product = p.x * 2;
"#;
let rust_expected = r#"
let p: Point;
let sum = p.x + p.y;
let product = p.x * 2;
"#;
assert!(c_code.contains("p.x + p.y"));
assert!(rust_expected.contains("p.x + p.y"));
}
#[test]
fn test_member_access_address_of() {
let c_code = r#"
struct Point p;
int* ptr = &p.x;
"#;
let rust_expected = r#"
let p: Point;
let ptr = &p.x;
"#;
assert!(c_code.contains("&p.x"));
assert!(rust_expected.contains("&p.x"));
}
#[test]
fn test_member_access_mutable_pointer() {
let c_code = r#"
struct Point* ptr;
ptr->x = ptr->y + 10;
"#;
let rust_expected = r#"
let ptr: &mut Point;
ptr.x = ptr.y + 10;
"#;
assert!(c_code.contains("ptr->x = ptr->y"));
assert!(rust_expected.contains("ptr.x = ptr.y"));
}
#[test]
fn test_member_access_in_conditional() {
let c_code = r#"
struct Point p;
if (p.x > 0 && p.y > 0) {
printf("Positive\n");
}
"#;
let rust_expected = r#"
let p: Point;
if p.x > 0 && p.y > 0 {
println!("Positive");
}
"#;
assert!(c_code.contains("p.x > 0 && p.y > 0"));
assert!(rust_expected.contains("p.x > 0 && p.y > 0"));
}
#[test]
fn test_member_access_in_loop() {
let c_code = r#"
struct Counter {
int value;
int max;
};
struct Counter c;
while (c.value < c.max) {
c.value++;
}
"#;
let rust_expected = r#"
struct Counter {
value: i32,
max: i32,
}
let mut c: Counter;
while c.value < c.max {
c.value += 1;
}
"#;
assert!(c_code.contains("c.value < c.max"));
assert!(rust_expected.contains("c.value < c.max"));
}
#[test]
fn test_member_access_array_element() {
let c_code = r#"
struct Point points[10];
points[0].x = 5;
int y = points[5].y;
"#;
let rust_expected = r#"
let mut points: [Point; 10];
points[0].x = 5;
let y = points[5].y;
"#;
assert!(c_code.contains("points[0].x"));
assert!(rust_expected.contains("points[0].x"));
}
#[test]
fn test_member_access_pointer_arithmetic() {
let c_code = r#"
struct Point* ptr;
(ptr + 1)->x = 10;
"#;
let rust_expected = r#"
let ptr: &[Point];
ptr[1].x = 10;
"#;
assert!(c_code.contains("(ptr + 1)->x"));
assert!(rust_expected.contains("ptr[1].x"));
}
#[test]
fn test_member_access_deep_nesting() {
let c_code = r#"
struct Inner {
int value;
};
struct Middle {
struct Inner inner;
};
struct Outer {
struct Middle middle;
};
struct Outer o;
o.middle.inner.value = 42;
"#;
let rust_expected = r#"
struct Inner {
value: i32,
}
struct Middle {
inner: Inner,
}
struct Outer {
middle: Middle,
}
let mut o: Outer;
o.middle.inner.value = 42;
"#;
assert!(c_code.contains("o.middle.inner.value"));
assert!(rust_expected.contains("o.middle.inner.value"));
}
#[test]
fn test_member_access_return_value() {
let c_code = r#"
int get_x(struct Point p) {
return p.x;
}
int get_y_from_ptr(struct Point* ptr) {
return ptr->y;
}
"#;
let rust_expected = r#"
fn get_x(p: Point) -> i32 {
return p.x;
}
fn get_y_from_ptr(ptr: &Point) -> i32 {
return ptr.y;
}
"#;
assert!(c_code.contains("return p.x"));
assert!(c_code.contains("return ptr->y"));
assert!(rust_expected.contains("return p.x"));
assert!(rust_expected.contains("return ptr.y"));
}
#[test]
fn test_member_access_copy_between_structs() {
let c_code = r#"
struct Point p1, p2;
p1.x = p2.x;
p1.y = p2.y;
"#;
let rust_expected = r#"
let mut p1: Point;
let p2: Point;
p1.x = p2.x;
p1.y = p2.y;
"#;
assert!(c_code.contains("p1.x = p2.x"));
assert!(rust_expected.contains("p1.x = p2.x"));
}
#[test]
fn test_member_access_transformation_summary() {
let c_code = r#"
// Rule 1: Dot operator unchanged
struct.member
// Rule 2: Arrow becomes dot
ptr->member
// Rule 3: Explicit deref simplified
(*ptr).member
// Rule 4: Chained access
struct.nested.field
ptr->nested.field
// Rule 5: In expressions
x = struct.a + struct.b
// Rule 6: Address of member
&struct.field
// Rule 7: Array element member
array[i].field
"#;
let rust_expected = r#"
// Rule 1: Same syntax
struct.member
// Rule 2: Auto-deref (no arrow)
ptr.member
// Rule 3: Auto-deref
ptr.member
// Rule 4: All dots
struct.nested.field
ptr.nested.field
// Rule 5: Same in expressions
x = struct.a + struct.b
// Rule 6: Same syntax
&struct.field
// Rule 7: Same syntax
array[i].field
"#;
assert!(c_code.contains("struct.member"));
assert!(rust_expected.contains("struct.member"));
assert!(c_code.contains("ptr->member"));
assert!(rust_expected.contains("ptr.member"));
assert!(c_code.contains("(*ptr).member"));
assert!(c_code.contains("ptr->nested.field"));
assert!(rust_expected.contains("ptr.nested.field"));
}
}