use aegis_vm::vm_protect;
#[test]
fn test_struct_basic() {
#[vm_protect(level = "debug")]
fn create_struct() -> u64 {
struct Point {
x: u64,
y: u64,
}
let p = Point { x: 10, y: 20 };
p.x + p.y
}
assert_eq!(create_struct(), 30);
}
#[test]
fn test_struct_three_fields() {
#[vm_protect(level = "debug")]
fn three_fields() -> u64 {
struct Triple {
a: u64,
b: u64,
c: u64,
}
let t = Triple { a: 1, b: 2, c: 3 };
t.a + t.b + t.c
}
assert_eq!(three_fields(), 6);
}
#[test]
fn test_struct_field_assignment() {
#[vm_protect(level = "debug")]
fn modify_struct() -> u64 {
struct Counter {
value: u64,
}
let mut c = Counter { value: 0 };
c.value = 42;
c.value
}
assert_eq!(modify_struct(), 42);
}
#[test]
fn test_struct_multiple_assignments() {
#[vm_protect(level = "debug")]
fn swap_fields() -> u64 {
struct Pair {
first: u64,
second: u64,
}
let mut p = Pair { first: 10, second: 20 };
let temp = p.first;
p.first = p.second;
p.second = temp;
p.first + p.second * 100
}
assert_eq!(swap_fields(), 1020);
}
#[test]
fn test_struct_in_expression() {
#[vm_protect(level = "debug")]
fn distance_squared() -> u64 {
struct Point {
x: u64,
y: u64,
}
let p = Point { x: 3, y: 4 };
p.x * p.x + p.y * p.y
}
assert_eq!(distance_squared(), 25);
}
#[test]
fn test_struct_in_condition() {
#[vm_protect(level = "debug")]
fn check_threshold() -> u64 {
struct Measurement {
value: u64,
threshold: u64,
}
let m = Measurement { value: 75, threshold: 50 };
if m.value > m.threshold {
1
} else {
0
}
}
assert_eq!(check_threshold(), 1);
}
#[test]
fn test_struct_in_loop() {
#[vm_protect(level = "debug")]
fn accumulate() -> u64 {
struct Accumulator {
sum: u64,
count: u64,
}
let mut acc = Accumulator { sum: 0, count: 0 };
for i in 0..5 {
acc.sum = acc.sum + i;
acc.count = acc.count + 1;
}
acc.sum + acc.count * 1000
}
assert_eq!(accumulate(), 5010);
}
#[test]
fn test_multiple_structs() {
#[vm_protect(level = "debug")]
fn two_structs() -> u64 {
struct PointA {
x: u64,
y: u64,
}
struct PointB {
a: u64,
b: u64,
}
let p1 = PointA { x: 10, y: 20 };
let p2 = PointB { a: 100, b: 200 };
p1.x + p1.y + p2.a + p2.b
}
assert_eq!(two_structs(), 330);
}
#[test]
fn test_unit_struct() {
#[vm_protect(level = "debug")]
fn unit_struct() -> u64 {
struct Marker;
let _m = Marker; 42
}
assert_eq!(unit_struct(), 42);
}
#[test]
fn test_unit_struct_with_braces() {
#[vm_protect(level = "debug")]
fn unit_struct_braces() -> u64 {
struct Empty {}
let _e = Empty {}; 99
}
assert_eq!(unit_struct_braces(), 99);
}
#[test]
fn test_struct_standard() {
#[vm_protect(level = "standard")]
fn standard_struct() -> u64 {
struct Data {
key: u64,
value: u64,
}
let d = Data { key: 0xCAFE, value: 0xBABE };
d.key ^ d.value
}
let result = standard_struct();
assert_eq!(result, 0xCAFE ^ 0xBABE);
}
#[test]
fn test_struct_paranoid() {
#[vm_protect(level = "paranoid")]
fn paranoid_struct() -> u64 {
struct Secret {
a: u64,
b: u64,
}
let s = Secret { a: 123, b: 456 };
s.a + s.b
}
assert_eq!(paranoid_struct(), 579);
}
#[test]
fn test_struct_field_as_index() {
#[vm_protect(level = "debug")]
fn index_from_struct() -> u64 {
struct IndexHolder {
idx: u64,
}
let arr = [10, 20, 30, 40, 50];
let holder = IndexHolder { idx: 2 };
arr[holder.idx as usize]
}
assert_eq!(index_from_struct(), 30);
}
#[test]
fn test_struct_complex_init() {
#[vm_protect(level = "debug")]
fn complex_init() -> u64 {
struct Result {
sum: u64,
product: u64,
}
let a = 5;
let b = 7;
let r = Result {
sum: a + b,
product: a * b,
};
r.sum + r.product
}
assert_eq!(complex_init(), 47);
}
#[test]
fn test_struct_all_levels_equivalent() {
#[vm_protect(level = "debug")]
fn debug_impl() -> u64 {
struct Point { x: u64, y: u64 }
let p = Point { x: 100, y: 200 };
p.x * p.y
}
#[vm_protect(level = "standard")]
fn standard_impl() -> u64 {
struct Point { x: u64, y: u64 }
let p = Point { x: 100, y: 200 };
p.x * p.y
}
#[vm_protect(level = "paranoid")]
fn paranoid_impl() -> u64 {
struct Point { x: u64, y: u64 }
let p = Point { x: 100, y: 200 };
p.x * p.y
}
let debug_result = debug_impl();
let standard_result = standard_impl();
let paranoid_result = paranoid_impl();
assert_eq!(debug_result, 20000);
assert_eq!(standard_result, 20000);
assert_eq!(paranoid_result, 20000);
}
#[test]
fn test_field_init_shorthand() {
#[vm_protect(level = "debug")]
fn shorthand() -> u64 {
struct Point {
x: u64,
y: u64,
}
let x = 10;
let y = 20;
let p = Point { x, y }; p.x + p.y
}
assert_eq!(shorthand(), 30);
}
#[test]
fn test_field_init_mixed() {
#[vm_protect(level = "debug")]
fn mixed() -> u64 {
struct Triple {
a: u64,
b: u64,
c: u64,
}
let a = 1;
let c = 3;
let t = Triple { a, b: 2, c }; t.a + t.b + t.c
}
assert_eq!(mixed(), 6);
}
#[test]
fn test_functional_update_basic() {
#[vm_protect(level = "debug")]
fn update() -> u64 {
struct Point {
x: u64,
y: u64,
}
let base = Point { x: 1, y: 2 };
let updated = Point { x: 100, ..base }; updated.x + updated.y }
assert_eq!(update(), 102);
}
#[test]
fn test_functional_update_multiple() {
#[vm_protect(level = "debug")]
fn update_multi() -> u64 {
struct Config {
a: u64,
b: u64,
c: u64,
d: u64,
}
let base = Config { a: 1, b: 2, c: 3, d: 4 };
let updated = Config { b: 20, d: 40, ..base }; updated.a + updated.b + updated.c + updated.d }
assert_eq!(update_multi(), 64);
}
#[test]
fn test_functional_update_copy_all() {
#[vm_protect(level = "debug")]
fn copy_all() -> u64 {
struct Data {
x: u64,
y: u64,
}
let original = Data { x: 42, y: 58 };
let copy = Data { ..original }; copy.x + copy.y
}
assert_eq!(copy_all(), 100);
}
#[test]
fn test_functional_update_computed() {
#[vm_protect(level = "debug")]
fn computed() -> u64 {
struct Rect {
x: u64,
y: u64,
w: u64,
h: u64,
}
let r1 = Rect { x: 0, y: 0, w: 10, h: 20 };
let r2 = Rect { x: r1.x + 5, y: r1.y + 5, ..r1 }; r2.x + r2.y + r2.w + r2.h }
assert_eq!(computed(), 40);
}
#[test]
fn test_tuple_struct() {
#[vm_protect(level = "debug")]
fn tuple_struct() -> u64 {
struct Point(u64, u64);
let p = Point(10, 20);
p.0 + p.1
}
assert_eq!(tuple_struct(), 30);
}
#[test]
fn test_tuple_struct_triple() {
#[vm_protect(level = "debug")]
fn triple() -> u64 {
struct Vec3(u64, u64, u64);
let v = Vec3(1, 2, 3);
v.0 + v.1 + v.2
}
assert_eq!(triple(), 6);
}
#[test]
fn test_tuple_struct_mutation() {
#[vm_protect(level = "debug")]
fn mutate() -> u64 {
struct Pair(u64, u64);
let mut p = Pair(1, 2);
p.0 = 100;
p.0 + p.1 }
assert_eq!(mutate(), 102);
}
#[test]
fn test_tuple_struct_expr() {
#[vm_protect(level = "debug")]
fn distance() -> u64 {
struct Point(u64, u64);
let p = Point(3, 4);
p.0 * p.0 + p.1 * p.1 }
assert_eq!(distance(), 25);
}
#[test]
fn test_multiple_tuple_structs() {
#[vm_protect(level = "debug")]
fn multi_tuple() -> u64 {
struct Point(u64, u64);
struct Size(u64, u64);
let p = Point(10, 20);
let s = Size(100, 200);
p.0 + p.1 + s.0 + s.1 }
assert_eq!(multi_tuple(), 330);
}
#[test]
fn test_numeric_field_init() {
#[vm_protect(level = "debug")]
fn numeric_init() -> u64 {
struct Color(u64, u64, u64);
let c = Color(255, 128, 64);
c.0 + c.1 + c.2
}
assert_eq!(numeric_init(), 447);
}
#[test]
fn test_struct_many_fields() {
#[vm_protect(level = "debug")]
fn many_fields() -> u64 {
struct BigStruct {
a: u64,
b: u64,
c: u64,
d: u64,
e: u64,
f: u64,
g: u64,
h: u64,
}
let s = BigStruct {
a: 1, b: 2, c: 3, d: 4,
e: 5, f: 6, g: 7, h: 8,
};
s.a + s.b + s.c + s.d + s.e + s.f + s.g + s.h
}
assert_eq!(many_fields(), 36);
}
#[test]
fn test_struct_multiple_instances() {
#[vm_protect(level = "debug")]
fn multi_instances() -> u64 {
struct Point { x: u64, y: u64 }
let p1 = Point { x: 10, y: 20 };
let p2 = Point { x: 30, y: 40 };
let p3 = Point { x: 50, y: 60 };
p1.x + p2.y + p3.x + p1.y + p2.x + p3.y
}
assert_eq!(multi_instances(), 210);
}
#[test]
fn test_struct_complex_arithmetic() {
#[vm_protect(level = "debug")]
fn complex_math() -> u64 {
struct Calc {
base: u64,
mult: u64,
add: u64,
}
let c = Calc { base: 5, mult: 3, add: 7 };
(c.base * c.mult + c.add) * 2 + c.base
}
assert_eq!(complex_math(), 49);
}
#[test]
fn test_struct_bitwise() {
#[vm_protect(level = "debug")]
fn bitwise_ops() -> u64 {
struct Bits {
mask: u64,
value: u64,
shift: u64,
}
let b = Bits { mask: 0xFF, value: 0x12AB, shift: 4 };
(b.value & b.mask) | ((b.value >> b.shift) & b.mask)
}
assert_eq!(bitwise_ops(), 0xAB);
}
#[test]
fn test_struct_nested_loops() {
#[vm_protect(level = "debug")]
fn nested_loop_struct() -> u64 {
struct Counter { x: u64, y: u64, total: u64 }
let mut c = Counter { x: 0, y: 0, total: 0 };
for i in 0..3 {
c.x = c.x + 1;
for j in 0..4 {
c.y = c.y + 1;
c.total = c.total + i + j;
}
}
c.x * 1000 + c.y * 10 + c.total
}
assert_eq!(nested_loop_struct(), 3150);
}
#[test]
fn test_struct_conditional_update() {
#[vm_protect(level = "debug")]
fn conditional() -> u64 {
struct State { value: u64, flag: u64 }
let mut s = State { value: 10, flag: 1 };
if s.flag > 0 {
s.value = s.value * 2;
}
if s.value > 15 {
s.flag = 0;
}
s.value * 100 + s.flag
}
assert_eq!(conditional(), 2000);
}
#[test]
fn test_struct_while_loop() {
#[vm_protect(level = "debug")]
fn while_loop_struct() -> u64 {
struct Iterator { current: u64, step: u64, limit: u64 }
let mut iter = Iterator { current: 0, step: 7, limit: 50 };
let mut count = 0;
while iter.current < iter.limit {
iter.current = iter.current + iter.step;
count = count + 1;
}
count * 1000 + iter.current
}
assert_eq!(while_loop_struct(), 8056);
}
#[test]
fn test_struct_comparison_chain() {
#[vm_protect(level = "debug")]
fn comparison_chain() -> u64 {
struct Range { min: u64, val: u64, max: u64 }
let r = Range { min: 10, val: 25, max: 50 };
if r.val >= r.min {
if r.val <= r.max {
1 } else {
2 }
} else {
3 }
}
assert_eq!(comparison_chain(), 1);
}
#[test]
fn test_struct_field_reuse() {
#[vm_protect(level = "debug")]
fn field_reuse() -> u64 {
struct Num { v: u64 }
let n = Num { v: 5 };
n.v + n.v * n.v + n.v * n.v * n.v
}
assert_eq!(field_reuse(), 155);
}
#[test]
fn test_struct_field_from_struct() {
#[vm_protect(level = "debug")]
fn struct_from_struct() -> u64 {
struct Input { a: u64, b: u64 }
struct Output { sum: u64, prod: u64 }
let input = Input { a: 6, b: 7 };
let output = Output {
sum: input.a + input.b,
prod: input.a * input.b,
};
output.sum + output.prod
}
assert_eq!(struct_from_struct(), 55);
}
#[test]
fn test_struct_field_swap() {
#[vm_protect(level = "debug")]
fn field_swap() -> u64 {
struct Pair { left: u64, right: u64 }
let mut p = Pair { left: 100, right: 200 };
let temp = p.left;
p.left = p.right;
p.right = temp;
p.left * 1000 + p.right
}
assert_eq!(field_swap(), 200100);
}
#[test]
fn test_struct_fibonacci() {
#[vm_protect(level = "debug")]
fn fib_struct() -> u64 {
struct Fib { prev: u64, curr: u64 }
let mut f = Fib { prev: 0, curr: 1 };
for _i in 0..10 {
let next = f.prev + f.curr;
f.prev = f.curr;
f.curr = next;
}
f.curr
}
assert_eq!(fib_struct(), 89);
}
#[test]
fn test_struct_accumulator_pattern() {
#[vm_protect(level = "debug")]
fn accumulator() -> u64 {
struct Stats { sum: u64, count: u64, min: u64, max: u64 }
let mut stats = Stats { sum: 0, count: 0, min: 999, max: 0 };
let values = [10, 25, 5, 30, 15];
for i in 0..5 {
let v = values[i];
stats.sum = stats.sum + v;
stats.count = stats.count + 1;
if v < stats.min {
stats.min = v;
}
if v > stats.max {
stats.max = v;
}
}
stats.sum + stats.count * 100 + stats.min * 10 + stats.max
}
assert_eq!(accumulator(), 665);
}
#[test]
fn test_struct_loop_break() {
#[vm_protect(level = "debug")]
fn loop_break() -> u64 {
struct Search { target: u64, found_at: u64 }
let mut s = Search { target: 25, found_at: 999 };
let arr = [10, 15, 20, 25, 30, 35];
for i in 0..6 {
if arr[i] == s.target {
s.found_at = i as u64;
break;
}
}
s.found_at
}
assert_eq!(loop_break(), 3);
}
#[test]
fn test_struct_loop_continue() {
#[vm_protect(level = "debug")]
fn loop_continue() -> u64 {
struct Filter { threshold: u64, sum: u64 }
let mut f = Filter { threshold: 15, sum: 0 };
let arr = [10, 20, 5, 25, 12, 30];
for i in 0..6 {
if arr[i] < f.threshold {
continue;
}
f.sum = f.sum + arr[i];
}
f.sum
}
assert_eq!(loop_continue(), 75);
}