1use ::{
5 fs2::FileExt,
6 std::{
7 fs::File,
8 io::{self, SeekFrom, prelude::*},
9 ops::{Deref, DerefMut},
10 thread::panicking,
11 },
12};
13
14#[derive(Debug)]
16pub struct FileLock<'a>(pub &'a File);
17
18impl<'a> FileLock<'a> {
19 pub fn try_wrap_shared(f: &'a File) -> io::Result<Self> {
22 f.try_lock_shared()?;
23 Ok(Self(f))
24 }
25
26 pub fn wrap_shared(f: &'a File) -> io::Result<Self> {
29 f.lock_shared()?;
30 Ok(Self(f))
31 }
32
33 pub fn try_wrap_exclusive(f: &'a File) -> io::Result<Self> {
36 f.try_lock_exclusive()?;
37 Ok(Self(f))
38 }
39
40 pub fn wrap_exclusive(f: &'a File) -> io::Result<Self> {
43 f.lock_exclusive()?;
44 Ok(Self(f))
45 }
46}
47
48impl<'a> Write for FileLock<'a> {
49 #[inline(always)]
50 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
51 self.0.write(buf)
52 }
53
54 #[inline(always)]
55 fn flush(&mut self) -> io::Result<()> {
56 self.0.flush()
57 }
58}
59
60impl<'a> Read for FileLock<'a> {
61 #[inline(always)]
62 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
63 self.0.read(buf)
64 }
65}
66
67impl<'a> Seek for FileLock<'a> {
68 #[inline(always)]
69 fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
70 self.0.seek(pos)
71 }
72}
73
74impl<'a> Deref for FileLock<'a> {
75 type Target = &'a File;
76
77 #[inline(always)]
78 fn deref(&self) -> &Self::Target {
79 &self.0
80 }
81}
82
83impl<'a> DerefMut for FileLock<'a> {
84 #[inline(always)]
85 fn deref_mut(&mut self) -> &mut Self::Target {
86 &mut self.0
87 }
88}
89
90impl<'a> Drop for FileLock<'a> {
91 fn drop(&mut self) {
92 if let Err(e) = self.0.unlock() {
93 if panicking() {
94 eprintln!("error unlocking file lock: {}", e)
95 } else {
96 panic!("error unlocking file lock: {}", e)
97 }
98 }
99 }
100}