mirror of
https://github.com/gitbutlerapp/gitbutler.git
synced 2024-12-20 08:01:46 +03:00
26c39f2a3f
This better expresses what it does, and leaves the `gitbutler-app` in the top-level where it can serve as visible entrypoint.
52 lines
1.3 KiB
Rust
52 lines
1.3 KiB
Rust
use std::sync::{Arc, Mutex};
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct Dir {
|
|
inner: Arc<Inner>,
|
|
}
|
|
|
|
impl Dir {
|
|
pub fn new<P: AsRef<std::path::Path>>(path: P) -> Result<Self, std::io::Error> {
|
|
Inner::new(path).map(Arc::new).map(|inner| Self { inner })
|
|
}
|
|
|
|
pub fn batch<R>(
|
|
&self,
|
|
action: impl FnOnce(&std::path::Path) -> R,
|
|
) -> Result<R, std::io::Error> {
|
|
self.inner.batch(action)
|
|
}
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
struct Inner {
|
|
path: std::path::PathBuf,
|
|
flock: Mutex<fslock::LockFile>,
|
|
}
|
|
|
|
impl Inner {
|
|
fn new<P: AsRef<std::path::Path>>(path: P) -> Result<Self, std::io::Error> {
|
|
let path = path.as_ref().to_path_buf();
|
|
if !path.exists() {
|
|
std::fs::create_dir_all(&path)?;
|
|
} else if !path.is_dir() {
|
|
return Err(std::io::Error::new(
|
|
std::io::ErrorKind::NotFound,
|
|
format!("{} is not a directory", path.display()),
|
|
));
|
|
}
|
|
let flock = fslock::LockFile::open(&path.with_extension("lock")).map(Mutex::new)?;
|
|
Ok(Self { path, flock })
|
|
}
|
|
|
|
fn batch<R>(&self, action: impl FnOnce(&std::path::Path) -> R) -> Result<R, std::io::Error> {
|
|
let mut flock = self.flock.lock().unwrap();
|
|
|
|
flock.lock()?;
|
|
let result = action(&self.path);
|
|
flock.unlock()?;
|
|
|
|
Ok(result)
|
|
}
|
|
}
|