From 1abb26099772b4c23d03479ed5a76c3547e371dd Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 7 May 2023 16:25:05 +0200 Subject: [PATCH] io/fs: add new module with filesystem access helpers Wrappers around std::fs with error messages, as well as a create_with_tmpfile() helper. --- src/io/fs.rs | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/io/mod.rs | 1 + 2 files changed, 62 insertions(+) create mode 100644 src/io/fs.rs diff --git a/src/io/fs.rs b/src/io/fs.rs new file mode 100644 index 0000000..46e8726 --- /dev/null +++ b/src/io/fs.rs @@ -0,0 +1,61 @@ +use std::{ + fs::{self, File}, + io::{BufWriter, Write}, + path::{Path, PathBuf}, +}; + +use anyhow::{Context, Ok, Result}; + +fn tmpfile_name(path: &Path) -> PathBuf { + let mut file_name = path.file_name().unwrap_or_default().to_os_string(); + file_name.push(".tmp"); + + let mut ret = path.to_path_buf(); + ret.set_file_name(file_name); + ret +} + +pub fn create_dir_all(path: &Path) -> Result<()> { + fs::create_dir_all(path) + .with_context(|| format!("Failed to create directory {}", path.display(),)) +} + +pub fn rename(from: &Path, to: &Path) -> Result<()> { + fs::rename(from, to) + .with_context(|| format!("Failed to rename {} to {}", from.display(), to.display())) +} + +pub fn create(path: &Path, f: F) -> Result +where + F: FnOnce(&mut BufWriter) -> Result, +{ + (|| { + let file = File::create(path)?; + let mut writer = BufWriter::new(file); + + let ret = f(&mut writer)?; + writer.flush()?; + + Ok(ret) + })() + .with_context(|| format!("Failed to write file {}", path.display())) +} + +pub fn create_with_tmpfile(path: &Path, f: F) -> Result +where + F: FnOnce(&mut BufWriter) -> Result, +{ + let tmp_path = tmpfile_name(path); + + let ret = (|| { + let ret = create(&tmp_path, f)?; + rename(&tmp_path, path)?; + Ok(ret) + })(); + + if ret.is_err() { + let _ = fs::remove_file(&tmp_path); + } + + ret +} diff --git a/src/io/mod.rs b/src/io/mod.rs index 4098f3b..681d75d 100644 --- a/src/io/mod.rs +++ b/src/io/mod.rs @@ -1,3 +1,4 @@ pub mod data; +pub mod fs; pub mod region; pub mod storage;