gitbutler/crates/gitbutler-core/src/storage.rs
Sebastian Thiel 72291ce4cb
chore: align 'app' and 'lib' crates imports.
This is done one-time (for now) using a nightly feature of cargo-fmt
as defined in `rustfmt-nightly.toml.`

It's planned to make this the default so imports will always be sorted.
For now it can be run manually with:
    cargo +nightly fmt -- --config-path rustfmt-nightly.toml
or
    pnpm rustfmtTBD
 Please enter the message for your patch. Lines starting with
2024-03-30 22:43:16 +01:00

73 lines
2.2 KiB
Rust

#[cfg(target_family = "unix")]
use std::os::unix::prelude::*;
use std::{
fs,
path::{Path, PathBuf},
sync::{Arc, RwLock},
};
#[derive(Debug, Default, Clone)]
pub struct Storage {
local_data_dir: Arc<RwLock<PathBuf>>,
}
#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error(transparent)]
IO(#[from] std::io::Error),
}
impl Storage {
pub fn new<P: AsRef<Path>>(local_data_dir: P) -> Storage {
Storage {
local_data_dir: Arc::new(RwLock::new(local_data_dir.as_ref().to_path_buf())),
}
}
pub fn read<P: AsRef<Path>>(&self, path: P) -> Result<Option<String>, Error> {
let local_data_dir = self.local_data_dir.read().unwrap();
let file_path = local_data_dir.join(path);
if !file_path.exists() {
return Ok(None);
}
let contents = fs::read_to_string(&file_path).map_err(Error::IO)?;
Ok(Some(contents))
}
pub fn write<P: AsRef<Path>>(&self, path: P, content: &str) -> Result<(), Error> {
let local_data_dir = self.local_data_dir.write().unwrap();
let file_path = local_data_dir.join(path);
let dir = file_path.parent().unwrap();
if !dir.exists() {
fs::create_dir_all(dir).map_err(Error::IO)?;
}
fs::write(&file_path, content).map_err(Error::IO)?;
// Set the permissions to be user-only. We can't actually
// do this on Windows, so we ignore that platform.
#[cfg(target_family = "unix")]
{
let metadata = fs::metadata(file_path.clone())?;
let mut permissions = metadata.permissions();
permissions.set_mode(0o600); // User read/write
fs::set_permissions(file_path.clone(), permissions)?;
}
Ok(())
}
pub fn delete<P: AsRef<Path>>(&self, path: P) -> Result<(), Error> {
let local_data_dir = self.local_data_dir.write().unwrap();
let file_path = local_data_dir.join(path);
if !file_path.exists() {
return Ok(());
}
if file_path.is_dir() {
fs::remove_dir_all(file_path.clone()).map_err(Error::IO)?;
} else {
fs::remove_file(file_path.clone()).map_err(Error::IO)?;
}
Ok(())
}
}