1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
use std::env;
use std::path::{Path, PathBuf};
/// RIIA directory change object.
///
/// Creating an instance of this object represents storing the current
/// directory and then switching to the requested directory. Dropping it
/// causes the directory to be switched back to the original directory.
///
/// # Notes
/// There's no ergonomic way to return errors from `Drop` handlers. If it is
/// unable switch back to the original directory, this will be lost to the
/// application, although an error will be printed on stderr.
pub struct DirSwitch {
old: PathBuf
}
impl DirSwitch {
/// Switch the current directory, and prepare for returning to the original.
pub fn switch<P: AsRef<Path>>(newdir: P) -> Result<Self, std::io::Error> {
let old = env::current_dir()?;
env::set_current_dir(newdir.as_ref())?;
Ok(Self { old })
}
}
impl Drop for DirSwitch {
/// Return to the original directory.
fn drop(&mut self) {
if let Err(e) = env::set_current_dir(&self.old) {
eprintln!("Unable to return to {}; {}", self.old.display(), e);
}
}
}
// vim: set ft=rust et sw=2 ts=2 sts=2 cinoptions=2 tw=79 :