virtual_fs/
arc_file.rs

1//! Used for sharing references to the same file across multiple file systems,
2//! effectively this is a symbolic link without all the complex path redirection
3
4use crate::{ClonableVirtualFile, VirtualFile};
5use std::pin::Pin;
6use std::task::{Context, Poll};
7use std::{
8    io::{self, *},
9    sync::{Arc, Mutex},
10};
11use tokio::io::{AsyncRead, AsyncSeek, AsyncWrite};
12
13#[derive(Debug)]
14pub struct ArcFile<T>
15where
16    T: VirtualFile + Send + Sync + 'static,
17{
18    inner: Arc<Mutex<Box<T>>>,
19}
20
21impl<T> ArcFile<T>
22where
23    T: VirtualFile + Send + Sync + 'static,
24{
25    pub fn new(inner: Box<T>) -> Self {
26        Self {
27            inner: Arc::new(Mutex::new(inner)),
28        }
29    }
30}
31
32impl<T> AsyncSeek for ArcFile<T>
33where
34    T: VirtualFile + Send + Sync + 'static,
35{
36    fn start_seek(self: Pin<&mut Self>, position: SeekFrom) -> io::Result<()> {
37        let mut guard = self.inner.lock().unwrap();
38        let file = Pin::new(guard.as_mut());
39        file.start_seek(position)
40    }
41    fn poll_complete(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<u64>> {
42        let mut guard = self.inner.lock().unwrap();
43        let file = Pin::new(guard.as_mut());
44        file.poll_complete(cx)
45    }
46}
47
48impl<T> AsyncWrite for ArcFile<T>
49where
50    T: VirtualFile + Send + Sync + 'static,
51{
52    fn poll_write(
53        self: Pin<&mut Self>,
54        cx: &mut Context<'_>,
55        buf: &[u8],
56    ) -> Poll<io::Result<usize>> {
57        let mut guard = self.inner.lock().unwrap();
58        let file = Pin::new(guard.as_mut());
59        file.poll_write(cx, buf)
60    }
61    fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
62        let mut guard = self.inner.lock().unwrap();
63        let file = Pin::new(guard.as_mut());
64        file.poll_flush(cx)
65    }
66    fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
67        let mut guard = self.inner.lock().unwrap();
68        let file = Pin::new(guard.as_mut());
69        file.poll_shutdown(cx)
70    }
71    fn poll_write_vectored(
72        self: Pin<&mut Self>,
73        cx: &mut Context<'_>,
74        bufs: &[IoSlice<'_>],
75    ) -> Poll<io::Result<usize>> {
76        let mut guard = self.inner.lock().unwrap();
77        let file = Pin::new(guard.as_mut());
78        file.poll_write_vectored(cx, bufs)
79    }
80    fn is_write_vectored(&self) -> bool {
81        let mut guard = self.inner.lock().unwrap();
82        let file = Pin::new(guard.as_mut());
83        file.is_write_vectored()
84    }
85}
86
87impl<T> AsyncRead for ArcFile<T>
88where
89    T: VirtualFile + Send + Sync + 'static,
90{
91    fn poll_read(
92        self: Pin<&mut Self>,
93        cx: &mut Context<'_>,
94        buf: &mut tokio::io::ReadBuf<'_>,
95    ) -> Poll<io::Result<()>> {
96        let mut guard = self.inner.lock().unwrap();
97        let file = Pin::new(guard.as_mut());
98        file.poll_read(cx, buf)
99    }
100}
101
102impl<T> VirtualFile for ArcFile<T>
103where
104    T: VirtualFile + Send + Sync + 'static,
105{
106    fn last_accessed(&self) -> u64 {
107        let inner = self.inner.lock().unwrap();
108        inner.last_accessed()
109    }
110    fn last_modified(&self) -> u64 {
111        let inner = self.inner.lock().unwrap();
112        inner.last_modified()
113    }
114    fn created_time(&self) -> u64 {
115        let inner = self.inner.lock().unwrap();
116        inner.created_time()
117    }
118    fn set_times(&mut self, atime: Option<u64>, mtime: Option<u64>) -> crate::Result<()> {
119        let mut inner = self.inner.lock().unwrap();
120        inner.set_times(atime, mtime)
121    }
122    fn size(&self) -> u64 {
123        let inner = self.inner.lock().unwrap();
124        inner.size()
125    }
126    fn set_len(&mut self, new_size: u64) -> crate::Result<()> {
127        let mut inner = self.inner.lock().unwrap();
128        inner.set_len(new_size)
129    }
130    fn unlink(&mut self) -> crate::Result<()> {
131        let mut inner = self.inner.lock().unwrap();
132        inner.unlink()
133    }
134    fn is_open(&self) -> bool {
135        let inner = self.inner.lock().unwrap();
136        inner.is_open()
137    }
138    fn get_special_fd(&self) -> Option<u32> {
139        let inner = self.inner.lock().unwrap();
140        inner.get_special_fd()
141    }
142    fn poll_read_ready(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<usize>> {
143        let mut inner = self.inner.lock().unwrap();
144        let inner = Pin::new(inner.as_mut());
145        inner.poll_read_ready(cx)
146    }
147    fn poll_write_ready(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<usize>> {
148        let mut inner = self.inner.lock().unwrap();
149        let inner = Pin::new(inner.as_mut());
150        inner.poll_write_ready(cx)
151    }
152}
153
154impl<T> Clone for ArcFile<T>
155where
156    T: VirtualFile + Send + Sync + 'static,
157{
158    fn clone(&self) -> Self {
159        ArcFile {
160            inner: self.inner.clone(),
161        }
162    }
163}
164
165impl<T> ClonableVirtualFile for ArcFile<T>
166where
167    T: VirtualFile + Send + Sync + 'static,
168    T: Clone,
169{
170}
171
172impl<T> Default for ArcFile<T>
173where
174    T: VirtualFile + Send + Sync + 'static,
175    T: Default,
176{
177    fn default() -> Self {
178        Self {
179            inner: Arc::new(Mutex::new(Box::default())),
180        }
181    }
182}