Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Shared via Rust Playground
macro_rules! twixt {
(($cond:expr; $after:expr) { $($body:tt)* } else { $($els:tt)* }) => {{
if $cond {
struct Doop;
impl Drop for Doop { fn drop(&mut self) { $after; } }
let _d = Doop;
$($body)*
} else {
$($els)*
}
}};
(($cond:expr; $after:expr) { $($body:tt)* }) => {
twixt!(($cond; $after) { $($body)* } else {})
}
}
#[test]
fn test() {
use std::sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT, Ordering};
static LOCK: AtomicBool = ATOMIC_BOOL_INIT;
fn get_lock() -> bool {
!LOCK.compare_and_swap(false, true, Ordering::SeqCst)
}
fn release_lock() {
LOCK.compare_and_swap(true, false, Ordering::SeqCst);
}
assert!(!LOCK.load(Ordering::SeqCst));
twixt!((get_lock(); release_lock()) {
assert!(LOCK.load(Ordering::SeqCst));
println!("acquired lock!");
twixt!((get_lock(); release_lock()) {
println!("uh oh, recursively acquired lock");
assert!(false);
});
} else {
println!("could not acquire lock!");
});
assert!(!LOCK.load(Ordering::SeqCst));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment