spacetimedb_fs_utils/
lib.rs

1use std::io::Write;
2use std::path::Path;
3
4pub mod compression;
5pub mod dir_trie;
6pub mod lockfile;
7
8pub fn create_parent_dir(file: &Path) -> Result<(), std::io::Error> {
9    // If the path doesn't have a parent,
10    // i.e. is a single-component path with just a root or is empty,
11    // do nothing.
12    let Some(parent) = file.parent() else {
13        return Ok(());
14    };
15
16    // If the `file` path is a relative path with no directory component,
17    // `parent` will be the empty path.
18    // In this case, do not attempt to create a directory.
19    if parent == Path::new("") {
20        return Ok(());
21    }
22
23    // If the `file` path has a directory component,
24    // do `create_dir_all` to ensure it exists.
25    // If `parent` already exists as a directory, this is a no-op.
26    std::fs::create_dir_all(parent)
27}
28
29pub fn atomic_write(file_path: &Path, data: String) -> anyhow::Result<()> {
30    let mut temp_path = file_path.to_path_buf();
31    let mut temp_file: std::fs::File;
32    loop {
33        temp_path.set_extension(format!(".tmp{}", rand::random::<u32>()));
34        let opened = std::fs::OpenOptions::new()
35            .write(true)
36            .create_new(true)
37            .open(&temp_path);
38        if let Ok(file) = opened {
39            temp_file = file;
40            break;
41        }
42    }
43    temp_file.write_all(data.as_bytes())?;
44    std::fs::rename(&temp_path, file_path)?;
45    Ok(())
46}