disk_utils 0.0.1

Data structures that use the disk
Documentation
use std::any::Any;
use std::fs;
use std::fs::{File, OpenOptions};
use std::io;
use std::ops::FnOnce;
use std::panic;
use std::panic::{RefUnwindSafe, UnwindSafe};
use std::path::Path;
use std::result;

#[derive(Debug)]
pub enum TestFileError {
    IoError(io::Error),
    ThreadError(Box<Any + Send + 'static>),
}

impl From<io::Error> for TestFileError {
    fn from(err: io::Error) -> TestFileError {
        TestFileError::IoError(err)
    }
}

impl From<Box<Any + Send + 'static>> for TestFileError {
    fn from(err: Box<Any + Send + 'static>) -> TestFileError {
        TestFileError::ThreadError(err)
    }
}

pub type Result<T> = result::Result<T, TestFileError>;

pub fn create_test_file<P: AsRef<Path> + ?Sized + RefUnwindSafe,
                        F: FnOnce(&P, File) -> R + UnwindSafe,
                        R>
    (path: &P,
     fun: F)
     -> Result<R> {
    let file = OpenOptions::new()
        .read(true)
        .append(true)
        .create(true)
        .open(path)?;

    let result = panic::catch_unwind(move || fun(path, file));
    fs::remove_file(path)?;
    Ok(result?)
}

pub fn create_two_test_files<P1: AsRef<Path> + ?Sized + RefUnwindSafe,
                             P2: AsRef<Path> + ?Sized + RefUnwindSafe,
                             F: FnOnce(&P1, &P2, File, File) -> R + UnwindSafe,
                             R>
    (path1: &P1,
     path2: &P2,
     fun: F)
     -> Result<R> {
    let file1 = OpenOptions::new()
        .read(true)
        .append(true)
        .create(true)
        .open(path1)?;
    let file2 = OpenOptions::new()
        .read(true)
        .append(true)
        .create(true)
        .open(path2)?;
    let result = panic::catch_unwind(move || fun(path1, path2, file1, file2));
    fs::remove_file(path1)?;
    fs::remove_file(path2)?;
    Ok(result?)
}