use borrowscope_macro::trace_borrow;
use borrowscope_runtime::*;
#[derive(Debug)]
struct Point {
x: i32,
y: i32,
}
#[derive(Debug)]
struct Rectangle {
top_left: Point,
bottom_right: Point,
}
#[trace_borrow]
fn struct_basic() {
let p = Point { x: 10, y: 20 };
println!("Point: {:?}", p);
}
#[trace_borrow]
fn struct_nested() {
let rect = Rectangle {
top_left: Point { x: 0, y: 0 },
bottom_right: Point { x: 100, y: 100 },
};
println!("Rectangle: {:?}", rect);
}
#[trace_borrow]
fn struct_update() {
let p1 = Point { x: 10, y: 20 };
let p2 = Point { x: 30, ..p1 };
println!("p1: {:?}, p2: {:?}", p1, p2);
}
#[trace_borrow]
fn tuple_basic() {
let t = (1, "hello", 3.14);
println!("Tuple: {:?}", t);
}
#[trace_borrow]
fn tuple_nested() {
let t = ((1, 2), (3, 4), (5, 6));
println!("Nested tuple: {:?}", t);
}
#[trace_borrow]
fn tuple_destructure() {
let t = (10, 20, 30);
let (a, b, c) = t;
println!("a={}, b={}, c={}", a, b, c);
}
#[trace_borrow]
fn array_basic() {
let arr = [1, 2, 3, 4, 5];
println!("Array: {:?}", arr);
}
#[trace_borrow]
fn array_repeat() {
let arr = [0; 10]; println!("Repeat array: {:?}", arr);
}
#[trace_borrow]
fn array_nested() {
let matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
println!("Matrix: {:?}", matrix);
}
#[trace_borrow]
fn range_basic() {
let r1 = 0..10; let r2 = 0..=10; println!("Range: {:?}", r1);
println!("RangeInclusive: {:?}", r2);
}
#[trace_borrow]
fn range_in_for() {
for i in 0..5 {
println!("i = {}", i);
}
}
#[trace_borrow]
fn range_slice() {
let arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
let slice = &arr[2..5];
println!("Slice: {:?}", slice);
}
#[trace_borrow]
fn cast_numeric() {
let x: i32 = 42;
let y = x as i64;
let z = x as f64;
println!("i32: {}, i64: {}, f64: {}", x, y, z);
}
#[trace_borrow]
fn cast_truncate() {
let big: i32 = 1000;
let small = big as i8; println!("i32: {}, i8: {}", big, small);
}
#[trace_borrow]
fn cast_char() {
let c = 'A';
let n = c as u32;
println!("char '{}' as u32: {}", c, n);
let n2: u32 = 66;
let c2 = n2 as u8 as char;
println!("u32 {} as char: '{}'", n2, c2);
}
#[trace_borrow]
fn closure_basic() {
let add = |a, b| a + b;
let result = add(2, 3);
println!("2 + 3 = {}", result);
}
#[trace_borrow]
fn closure_capture_ref() {
let x = 10;
let print_x = || println!("x = {}", x);
print_x();
println!("x is still: {}", x);
}
#[trace_borrow]
fn closure_capture_move() {
let s = String::from("hello");
let consume = move || println!("Consumed: {}", s);
consume();
}
#[trace_borrow]
fn closure_capture_mut() {
let mut count = 0;
let mut increment = || {
count += 1;
println!("Count: {}", count);
};
increment();
increment();
increment();
}
#[trace_borrow]
fn closure_as_argument() {
let numbers = vec![1, 2, 3, 4, 5];
let doubled: Vec<_> = numbers.iter().map(|x| x * 2).collect();
println!("Doubled: {:?}", doubled);
}
#[trace_borrow]
fn closure_returning() {
fn make_adder(x: i32) -> impl Fn(i32) -> i32 {
move |y| x + y
}
let add_5 = make_adder(5);
println!("5 + 10 = {}", add_5(10));
}
fn main() {
println!("=== Struct Basic ===");
reset();
struct_basic();
print_events("struct_basic");
println!("\n=== Struct Nested ===");
reset();
struct_nested();
print_events("struct_nested");
println!("\n=== Struct Update ===");
reset();
struct_update();
print_events("struct_update");
println!("\n=== Tuple Basic ===");
reset();
tuple_basic();
print_events("tuple_basic");
println!("\n=== Tuple Nested ===");
reset();
tuple_nested();
print_events("tuple_nested");
println!("\n=== Tuple Destructure ===");
reset();
tuple_destructure();
print_events("tuple_destructure");
println!("\n=== Array Basic ===");
reset();
array_basic();
print_events("array_basic");
println!("\n=== Array Repeat ===");
reset();
array_repeat();
print_events("array_repeat");
println!("\n=== Array Nested ===");
reset();
array_nested();
print_events("array_nested");
println!("\n=== Range Basic ===");
reset();
range_basic();
print_events("range_basic");
println!("\n=== Range in For ===");
reset();
range_in_for();
print_events("range_in_for");
println!("\n=== Range Slice ===");
reset();
range_slice();
print_events("range_slice");
println!("\n=== Cast Numeric ===");
reset();
cast_numeric();
print_events("cast_numeric");
println!("\n=== Cast Truncate ===");
reset();
cast_truncate();
print_events("cast_truncate");
println!("\n=== Cast Char ===");
reset();
cast_char();
print_events("cast_char");
println!("\n=== Closure Basic ===");
reset();
closure_basic();
print_events("closure_basic");
println!("\n=== Closure Capture Ref ===");
reset();
closure_capture_ref();
print_events("closure_capture_ref");
println!("\n=== Closure Capture Move ===");
reset();
closure_capture_move();
print_events("closure_capture_move");
println!("\n=== Closure Capture Mut ===");
reset();
closure_capture_mut();
print_events("closure_capture_mut");
println!("\n=== Closure as Argument ===");
reset();
closure_as_argument();
print_events("closure_as_argument");
println!("\n=== Closure Returning ===");
reset();
closure_returning();
print_events("closure_returning");
}
fn print_events(name: &str) {
let events = get_events();
println!("{} generated {} events:", name, events.len());
for (i, event) in events.iter().enumerate() {
println!(" {}: {:?}", i + 1, event);
}
}