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 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 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 pub fn lock_path(&self) -> &Path {
31 &self.lock_path
32 }
33
34 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 pub fn lock_path(&self) -> &Path {
71 &self.lock_path
72 }
73
74 pub fn resource_path(&self) -> PathBuf {
76 strip_lock_suffix(&self.lock_path)
77 }
78}