diff options
author | Luca Casonato <hello@lcas.dev> | 2023-04-12 15:13:32 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-04-12 15:13:32 +0200 |
commit | f90caa821c5a4acf28f7dec4071994ecf6f26e57 (patch) | |
tree | fa4af65399a16a9f2d17fa2b249f21be2c00b976 /ext/io/lib.rs | |
parent | 0e3f62d4446ae7b9a64dacf7befcaecede118222 (diff) |
refactor(ext/fs): abstract FS via FileSystem trait (#18599)
This commit abstracts out the specifics of the underlying system calls
FS operations behind a new `FileSystem` and `File` trait in the
`ext/fs` extension.
This allows other embedders to re-use ext/fs, but substituting in a
different FS backend.
This is likely not the final form of these traits. Eventually they will
be entirely `deno_core::Resource` agnostic, and will live in a seperate
crate.
---------
Co-authored-by: Bartek IwaĆczuk <biwanczuk@gmail.com>
Diffstat (limited to 'ext/io/lib.rs')
-rw-r--r-- | ext/io/lib.rs | 81 |
1 files changed, 57 insertions, 24 deletions
diff --git a/ext/io/lib.rs b/ext/io/lib.rs index 69f8c9da5..c85b4baf6 100644 --- a/ext/io/lib.rs +++ b/ext/io/lib.rs @@ -20,6 +20,7 @@ use once_cell::sync::Lazy; use std::borrow::Cow; use std::cell::RefCell; use std::fs::File as StdFile; +use std::io; use std::io::ErrorKind; use std::io::Read; use std::io::Write; @@ -452,21 +453,21 @@ impl StdFileResource { } } - fn with_inner_and_metadata<TResult>( + fn with_inner_and_metadata<TResult, E>( &self, action: impl FnOnce( &mut StdFileResourceInner, &Arc<Mutex<FileMetadata>>, - ) -> Result<TResult, AnyError>, - ) -> Result<TResult, AnyError> { + ) -> Result<TResult, E>, + ) -> Option<Result<TResult, E>> { match self.cell.try_borrow_mut() { Ok(mut cell) => { let mut file = cell.take().unwrap(); let result = action(&mut file.inner, &file.meta_data); cell.replace(file); - result + Some(result) } - Err(_) => Err(resource_unavailable()), + Err(_) => None, } } @@ -537,11 +538,16 @@ impl StdFileResource { } fn read_byob_sync(&self, buf: &mut [u8]) -> Result<usize, AnyError> { - self.with_inner_and_metadata(|inner, _| inner.read(buf).map_err(Into::into)) + self + .with_inner_and_metadata(|inner, _| inner.read(buf)) + .ok_or_else(resource_unavailable)? + .map_err(Into::into) } fn write_sync(&self, data: &[u8]) -> Result<usize, AnyError> { - self.with_inner_and_metadata(|inner, _| inner.write_and_maybe_flush(data)) + self + .with_inner_and_metadata(|inner, _| inner.write_and_maybe_flush(data)) + .ok_or_else(resource_unavailable)? } fn with_resource<F, R>( @@ -565,10 +571,19 @@ impl StdFileResource { F: FnOnce(&mut StdFile) -> Result<R, AnyError>, { Self::with_resource(state, rid, move |resource| { - resource.with_inner_and_metadata(move |inner, _| inner.with_file(f)) + resource + .with_inner_and_metadata(move |inner, _| inner.with_file(f)) + .ok_or_else(resource_unavailable)? }) } + pub fn with_file2<F, R>(self: Rc<Self>, f: F) -> Option<Result<R, io::Error>> + where + F: FnOnce(&mut StdFile) -> Result<R, io::Error>, + { + self.with_inner_and_metadata(move |inner, _| inner.with_file(f)) + } + pub fn with_file_and_metadata<F, R>( state: &mut OpState, rid: ResourceId, @@ -578,9 +593,11 @@ impl StdFileResource { F: FnOnce(&mut StdFile, &Arc<Mutex<FileMetadata>>) -> Result<R, AnyError>, { Self::with_resource(state, rid, move |resource| { - resource.with_inner_and_metadata(move |inner, metadata| { - inner.with_file(move |file| f(file, metadata)) - }) + resource + .with_inner_and_metadata(move |inner, metadata| { + inner.with_file(move |file| f(file, metadata)) + }) + .ok_or_else(resource_unavailable)? }) } @@ -602,6 +619,18 @@ impl StdFileResource { .await } + pub async fn with_file_blocking_task2<F, R: Send + 'static>( + self: Rc<Self>, + f: F, + ) -> Result<R, io::Error> + where + F: (FnOnce(&mut StdFile) -> Result<R, io::Error>) + Send + 'static, + { + self + .with_inner_blocking_task(move |inner| inner.with_file(f)) + .await + } + pub fn clone_file( state: &mut OpState, rid: ResourceId, @@ -616,13 +645,15 @@ impl StdFileResource { rid: u32, ) -> Result<std::process::Stdio, AnyError> { Self::with_resource(state, rid, |resource| { - resource.with_inner_and_metadata(|inner, _| match inner.kind { - StdFileResourceKind::File => { - let file = inner.file.try_clone()?; - Ok(file.into()) - } - _ => Ok(std::process::Stdio::inherit()), - }) + resource + .with_inner_and_metadata(|inner, _| match inner.kind { + StdFileResourceKind::File => { + let file = inner.file.try_clone()?; + Ok(file.into()) + } + _ => Ok(std::process::Stdio::inherit()), + }) + .ok_or_else(resource_unavailable)? }) } } @@ -679,8 +710,8 @@ impl Resource for StdFileResource { use std::os::unix::io::AsRawFd; self .with_inner_and_metadata(move |std_file, _| { - Ok(std_file.with_file(|f| f.as_raw_fd())) - }) + Ok::<_, ()>(std_file.with_file(|f| f.as_raw_fd())) + })? .ok() } } @@ -694,9 +725,11 @@ pub fn op_print( ) -> Result<(), AnyError> { let rid = if is_err { 2 } else { 1 }; StdFileResource::with_resource(state, rid, move |resource| { - resource.with_inner_and_metadata(|inner, _| { - inner.write_all_and_maybe_flush(msg.as_bytes())?; - Ok(()) - }) + resource + .with_inner_and_metadata(|inner, _| { + inner.write_all_and_maybe_flush(msg.as_bytes())?; + Ok(()) + }) + .ok_or_else(resource_unavailable)? }) } |