mirror of
https://github.com/denoland/deno.git
synced 2025-09-26 12:19:12 +00:00
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>
This commit is contained in:
parent
0e3f62d444
commit
f90caa821c
15 changed files with 3350 additions and 2488 deletions
|
@ -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)?
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue