From f90caa821c5a4acf28f7dec4071994ecf6f26e57 Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Wed, 12 Apr 2023 15:13:32 +0200 Subject: refactor(ext/fs): abstract FS via FileSystem trait (#18599) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- ext/io/lib.rs | 81 +++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 57 insertions(+), 24 deletions(-) (limited to 'ext/io/lib.rs') 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( + fn with_inner_and_metadata( &self, action: impl FnOnce( &mut StdFileResourceInner, &Arc>, - ) -> Result, - ) -> Result { + ) -> Result, + ) -> Option> { 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 { - 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 { - 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( @@ -565,10 +571,19 @@ impl StdFileResource { F: FnOnce(&mut StdFile) -> Result, { 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(self: Rc, f: F) -> Option> + where + F: FnOnce(&mut StdFile) -> Result, + { + self.with_inner_and_metadata(move |inner, _| inner.with_file(f)) + } + pub fn with_file_and_metadata( state: &mut OpState, rid: ResourceId, @@ -578,9 +593,11 @@ impl StdFileResource { F: FnOnce(&mut StdFile, &Arc>) -> Result, { 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( + self: Rc, + f: F, + ) -> Result + where + F: (FnOnce(&mut StdFile) -> Result) + 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 { 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)? }) } -- cgit v1.2.3