Skip to content

Instantly share code, notes, and snippets.

@sfackler
Created October 13, 2013 17:36
Show Gist options
  • Save sfackler/6965006 to your computer and use it in GitHub Desktop.
Save sfackler/6965006 to your computer and use it in GitHub Desktop.
use std::task;
pub enum UnwindMethod {
Success,
Failure,
Exit
}
pub struct ScopeGuard<'self> {
priv blk: &'self fn(),
priv method: UnwindMethod
}
#[unsafe_destructor]
impl<'self> Drop for ScopeGuard<'self> {
fn drop(&mut self) {
match self.method {
Success if task::failing() => (),
Failure if !task::failing() => (),
_ => (self.blk)()
}
}
}
pub fn scope<'a>(method: UnwindMethod, blk: &'a fn()) -> ScopeGuard<'a> {
ScopeGuard {
method: method,
blk: blk
}
}
#[cfg(test)]
mod test {
use super::{Success, Failure, Exit, scope};
use std::task;
#[test]
fn test_success() {
let mut a = 0;
{
let _scope = do scope(Success) { a += 1; };
}
assert_eq!(a, 1);
}
#[test]
fn test_success_failure() {
static mut a: int = 0;
let _: Result<(), ()> = do task::try {
let _scope = do scope(Success) { unsafe { a += 1; } };
fail!();
};
assert_eq!(unsafe { a }, 0);
}
#[test]
fn test_exit_success() {
let mut a = 0;
{
let _scope = do scope(Exit) { a += 1; };
}
assert_eq!(a, 1);
}
#[test]
fn test_exit_failure() {
static mut a: int = 0;
let _: Result<(), ()> = do task::try {
let _scope = do scope(Exit) { unsafe { a += 1; } };
fail!();
};
assert_eq!(unsafe { a }, 1);
}
#[test]
fn test_failure() {
static mut a: int = 0;
let _: Result<(), ()> = do task::try {
let _scope = do scope(Failure) { unsafe { a += 1; } };
fail!();
};
assert_eq!(unsafe { a }, 1);
}
#[test]
fn test_failure_success() {
let mut a = 0;
{
let _scope = do scope(Failure) { a += 1; };
}
assert_eq!(a, 0);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment