1use std::fs::File;
2use std::io::{Read, Seek, Write};
3
4impl From<File> for ClosableFile {
5 fn from(value: File) -> Self {
6 ClosableFile { inner: value }
7 }
8}
9
10impl From<ClosableFile> for File {
11 fn from(value: ClosableFile) -> Self {
12 value.inner
13 }
14}
15
16pub struct ClosableFile {
17 inner: File,
18}
19
20impl ClosableFile {
21 #[cfg(unix)]
22 pub fn close(self) -> std::io::Result<()> {
23 use std::os::fd::IntoRawFd;
24 let fd = self.inner.into_raw_fd();
25
26 match unsafe { libc::close(fd) } {
27 0 => Ok(()),
28 _ => Err(std::io::Error::last_os_error()),
29 }
30 }
31
32 #[cfg(not(unix))]
33 pub fn close(self) -> std::io::Result<()> {
34 Ok(())
35 }
36}
37
38impl AsMut<File> for ClosableFile {
39 fn as_mut(&mut self) -> &mut File {
40 &mut self.inner
41 }
42}
43
44impl AsRef<File> for ClosableFile {
45 fn as_ref(&self) -> &File {
46 &self.inner
47 }
48}
49
50impl Seek for ClosableFile {
51 fn seek(&mut self, pos: std::io::SeekFrom) -> std::io::Result<u64> {
52 self.inner.seek(pos)
53 }
54}
55
56impl Read for ClosableFile {
57 fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
58 self.inner.read(buf)
59 }
60}
61
62impl Write for ClosableFile {
63 fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
64 self.inner.write(buf)
65 }
66
67 fn flush(&mut self) -> std::io::Result<()> {
68 self.inner.flush()
69 }
70}
71
72pub trait WriteClose: Write {
73 fn close(self: Box<Self>) -> std::io::Result<()> {
74 Ok(())
75 }
76}
77
78impl WriteClose for ClosableFile {
79 fn close(self: Box<Self>) -> std::io::Result<()> {
80 let f = *self;
81 f.close()
82 }
83}