gix_lock/
file.rs

1use std::path::{Path, PathBuf};
2
3use crate::{File, Marker, DOT_LOCK_SUFFIX};
4
5fn strip_lock_suffix(lock_path: &Path) -> PathBuf {
6    let ext = lock_path
7        .extension()
8        .expect("at least our own extension")
9        .to_str()
10        .expect("no illegal UTF8 in extension");
11    lock_path.with_extension(ext.split_at(ext.len().saturating_sub(DOT_LOCK_SUFFIX.len())).0)
12}
13
14impl File {
15    /// Obtain a mutable reference to the write handle and call `f(out)` with it.
16    pub fn with_mut<T>(&mut self, f: impl FnOnce(&mut std::fs::File) -> std::io::Result<T>) -> std::io::Result<T> {
17        self.inner.with_mut(|tf| f(tf.as_file_mut())).and_then(|res| res)
18    }
19    /// Close the lock file to prevent further writes and to save system resources.
20    /// A call to [`Marker::commit()`] is allowed on the [`Marker`] to write changes back to the resource.
21    pub fn close(self) -> std::io::Result<Marker> {
22        Ok(Marker {
23            inner: self.inner.close()?,
24            created_from_file: true,
25            lock_path: self.lock_path,
26        })
27    }
28
29    /// Return the path at which the lock file resides
30    pub fn lock_path(&self) -> &Path {
31        &self.lock_path
32    }
33
34    /// Return the path at which the locked resource resides
35    pub fn resource_path(&self) -> PathBuf {
36        strip_lock_suffix(&self.lock_path)
37    }
38}
39
40mod io_impls {
41    use std::{io, io::SeekFrom};
42
43    use super::File;
44
45    impl io::Write for File {
46        fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
47            self.inner.with_mut(|f| f.write(buf))?
48        }
49
50        fn flush(&mut self) -> io::Result<()> {
51            self.inner.with_mut(io::Write::flush)?
52        }
53    }
54
55    impl io::Seek for File {
56        fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
57            self.inner.with_mut(|f| f.seek(pos))?
58        }
59    }
60
61    impl io::Read for File {
62        fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
63            self.inner.with_mut(|f| f.read(buf))?
64        }
65    }
66}
67
68impl Marker {
69    /// Return the path at which the lock file resides
70    pub fn lock_path(&self) -> &Path {
71        &self.lock_path
72    }
73
74    /// Return the path at which the locked resource resides
75    pub fn resource_path(&self) -> PathBuf {
76        strip_lock_suffix(&self.lock_path)
77    }
78}