1use std::path::{Path, PathBuf};
5
6use crate::dirs::create_dir_all;
7use crate::error::{Error, Result};
8
9pub struct FileLock {
11 _inner: fslock::LockFile,
12 path: PathBuf,
13}
14
15impl FileLock {
16 pub fn acquire(path: impl AsRef<Path>) -> Result<FileLock> {
19 let path = path.as_ref().to_path_buf();
20 if let Some(parent) = path.parent() {
21 create_dir_all(parent)?;
22 }
23 let mut lf = fslock::LockFile::open(&path).map_err(|e| Error::io(&path, e))?;
24 lf.lock().map_err(|e| Error::io(&path, e))?;
25 Ok(FileLock { _inner: lf, path })
26 }
27
28 pub fn try_acquire(path: impl AsRef<Path>) -> Result<Option<FileLock>> {
30 let path = path.as_ref().to_path_buf();
31 if let Some(parent) = path.parent() {
32 create_dir_all(parent)?;
33 }
34 let mut lf = fslock::LockFile::open(&path).map_err(|e| Error::io(&path, e))?;
35 if lf.try_lock().map_err(|e| Error::io(&path, e))? {
36 Ok(Some(FileLock { _inner: lf, path }))
37 } else {
38 Ok(None)
39 }
40 }
41
42 pub fn path(&self) -> &Path {
43 &self.path
44 }
45}