use borrowscope_macro::trace_borrow;
use borrowscope_runtime::*;
use std::sync::{Arc, Mutex, RwLock};
#[trace_borrow]
fn clone_string() {
let s1 = String::from("hello");
let s2 = s1.clone();
println!("s1: {}, s2: {}", s1, s2);
}
#[trace_borrow]
fn clone_vec() {
let v1 = vec![1, 2, 3, 4, 5];
let v2 = v1.clone();
println!("v1: {:?}, v2: {:?}", v1, v2);
}
#[trace_borrow]
fn clone_in_loop() {
let original = String::from("data");
let mut clones = Vec::new();
for i in 0..3 {
let cloned = original.clone();
clones.push(format!("{}-{}", cloned, i));
}
println!("Clones: {:?}", clones);
}
#[trace_borrow]
fn unwrap_option() {
let opt = Some(42);
let value = opt.unwrap();
println!("Unwrapped: {}", value);
}
#[trace_borrow]
fn unwrap_result() {
let result: Result<i32, &str> = Ok(100);
let value = result.unwrap();
println!("Unwrapped: {}", value);
}
#[trace_borrow]
fn expect_option() {
let opt = Some("hello");
let value = opt.expect("Should have a value");
println!("Expected: {}", value);
}
#[trace_borrow]
fn unwrap_or_default() {
let opt: Option<String> = None;
let value = opt.unwrap_or_default();
println!("Unwrap or default: '{}'", value);
}
#[trace_borrow]
fn unwrap_or_else() {
let opt: Option<i32> = None;
let value = opt.unwrap_or_else(|| {
println!("Computing default...");
42
});
println!("Unwrap or else: {}", value);
}
#[trace_borrow]
fn mutex_lock() {
let mutex = Mutex::new(vec![1, 2, 3]);
{
let mut guard = mutex.lock().unwrap();
guard.push(4);
println!("Inside lock: {:?}", guard);
}
println!("After lock released");
}
#[trace_borrow]
fn mutex_try_lock() {
let mutex = Mutex::new(42);
let result = mutex.try_lock();
match result {
Ok(guard) => println!("Got lock: {}", guard),
Err(_) => println!("Couldn't get lock"),
}
}
#[trace_borrow]
fn rwlock_read() {
let rwlock = RwLock::new(vec![1, 2, 3]);
let r1 = rwlock.read().unwrap();
let r2 = rwlock.read().unwrap();
println!("r1: {:?}, r2: {:?}", r1, r2);
}
#[trace_borrow]
fn rwlock_write() {
let rwlock = RwLock::new(vec![1, 2, 3]);
{
let mut w = rwlock.write().unwrap();
w.push(4);
println!("After write: {:?}", w);
}
let r = rwlock.read().unwrap();
println!("After release: {:?}", r);
}
#[trace_borrow]
fn arc_mutex_pattern() {
let shared = Arc::new(Mutex::new(0));
let clone1 = Arc::clone(&shared);
let clone2 = Arc::clone(&shared);
{
let mut guard = clone1.lock().unwrap();
*guard += 10;
}
{
let mut guard = clone2.lock().unwrap();
*guard += 20;
}
println!("Final value: {}", shared.lock().unwrap());
}
#[trace_borrow]
fn chained_methods() {
let s = String::from(" hello world ");
let result = s.trim().to_uppercase().clone();
println!("Result: {}", result);
}
fn main() {
println!("=== Clone String ===");
reset();
clone_string();
print_events("clone_string");
println!("\n=== Clone Vec ===");
reset();
clone_vec();
print_events("clone_vec");
println!("\n=== Clone in Loop ===");
reset();
clone_in_loop();
print_events("clone_in_loop");
println!("\n=== Unwrap Option ===");
reset();
unwrap_option();
print_events("unwrap_option");
println!("\n=== Unwrap Result ===");
reset();
unwrap_result();
print_events("unwrap_result");
println!("\n=== Expect Option ===");
reset();
expect_option();
print_events("expect_option");
println!("\n=== Unwrap Or Default ===");
reset();
unwrap_or_default();
print_events("unwrap_or_default");
println!("\n=== Unwrap Or Else ===");
reset();
unwrap_or_else();
print_events("unwrap_or_else");
println!("\n=== Mutex Lock ===");
reset();
mutex_lock();
print_events("mutex_lock");
println!("\n=== Mutex Try Lock ===");
reset();
mutex_try_lock();
print_events("mutex_try_lock");
println!("\n=== RwLock Read ===");
reset();
rwlock_read();
print_events("rwlock_read");
println!("\n=== RwLock Write ===");
reset();
rwlock_write();
print_events("rwlock_write");
println!("\n=== Arc Mutex Pattern ===");
reset();
arc_mutex_pattern();
print_events("arc_mutex_pattern");
println!("\n=== Chained Methods ===");
reset();
chained_methods();
print_events("chained_methods");
}
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);
}
}