diff options
| author | David Sherret <dsherret@users.noreply.github.com> | 2023-05-04 14:28:42 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-05-04 14:28:42 -0400 |
| commit | 5270c43e412cc636cd9923182169d166d181f78a (patch) | |
| tree | 640c90a70f7dd7bc91f5e942e1eaa5a7914ae46b /ext/fs | |
| parent | 4b645676d62fd595ecac47e24be1b83a3ba636c6 (diff) | |
refactor(ext/fs): boxed deno_fs::FileSystem (#18945)
1. Boxed `File` and `FileSystem` to allow more easily passing this
through the CLI code (as shown within this pr).
2. `StdFileResource` is now `FileResource`. `FileResource` now contains
an `Rc<dyn File>`.
Diffstat (limited to 'ext/fs')
| -rw-r--r-- | ext/fs/Cargo.toml | 4 | ||||
| -rw-r--r-- | ext/fs/interface.rs | 164 | ||||
| -rw-r--r-- | ext/fs/lib.rs | 135 | ||||
| -rw-r--r-- | ext/fs/ops.rs | 454 | ||||
| -rw-r--r-- | ext/fs/std_fs.rs | 411 |
5 files changed, 345 insertions, 823 deletions
diff --git a/ext/fs/Cargo.toml b/ext/fs/Cargo.toml index 10c71a543..f6d563b64 100644 --- a/ext/fs/Cargo.toml +++ b/ext/fs/Cargo.toml @@ -17,8 +17,8 @@ path = "lib.rs" async-trait.workspace = true deno_core.workspace = true deno_io.workspace = true -filetime = "0.2.16" -fs3 = "0.5.0" +filetime.workspace = true +fs3.workspace = true libc.workspace = true log.workspace = true rand.workspace = true diff --git a/ext/fs/interface.rs b/ext/fs/interface.rs index 184cb8096..1847b5982 100644 --- a/ext/fs/interface.rs +++ b/ext/fs/interface.rs @@ -1,6 +1,5 @@ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. -use std::io; use std::path::Path; use std::path::PathBuf; use std::rc::Rc; @@ -8,6 +7,10 @@ use std::rc::Rc; use serde::Deserialize; use serde::Serialize; +use deno_io::fs::File; +use deno_io::fs::FsResult; +use deno_io::fs::FsStat; + #[derive(Deserialize, Default, Debug, Clone, Copy)] #[serde(rename_all = "camelCase")] #[serde(default)] @@ -52,27 +55,6 @@ impl OpenOptions { } } -pub struct FsStat { - pub is_file: bool, - pub is_directory: bool, - pub is_symlink: bool, - pub size: u64, - - pub mtime: Option<u64>, - pub atime: Option<u64>, - pub birthtime: Option<u64>, - - pub dev: u64, - pub ino: u64, - pub mode: u32, - pub nlink: u64, - pub uid: u32, - pub gid: u32, - pub rdev: u64, - pub blksize: u64, - pub blocks: u64, -} - #[derive(Deserialize)] pub enum FsFileType { #[serde(rename = "file")] @@ -90,93 +72,25 @@ pub struct FsDirEntry { pub is_symlink: bool, } -pub enum FsError { - Io(io::Error), - FileBusy, - NotSupported, -} - -impl From<io::Error> for FsError { - fn from(err: io::Error) -> Self { - Self::Io(err) - } -} - -pub type FsResult<T> = Result<T, FsError>; - -#[async_trait::async_trait(?Send)] -pub trait File { - fn write_all_sync(self: Rc<Self>, buf: &[u8]) -> FsResult<()>; - async fn write_all_async(self: Rc<Self>, buf: Vec<u8>) -> FsResult<()>; - - fn read_all_sync(self: Rc<Self>) -> FsResult<Vec<u8>>; - async fn read_all_async(self: Rc<Self>) -> FsResult<Vec<u8>>; - - fn chmod_sync(self: Rc<Self>, pathmode: u32) -> FsResult<()>; - async fn chmod_async(self: Rc<Self>, mode: u32) -> FsResult<()>; - - fn seek_sync(self: Rc<Self>, pos: io::SeekFrom) -> FsResult<u64>; - async fn seek_async(self: Rc<Self>, pos: io::SeekFrom) -> FsResult<u64>; - - fn datasync_sync(self: Rc<Self>) -> FsResult<()>; - async fn datasync_async(self: Rc<Self>) -> FsResult<()>; - - fn sync_sync(self: Rc<Self>) -> FsResult<()>; - async fn sync_async(self: Rc<Self>) -> FsResult<()>; - - fn stat_sync(self: Rc<Self>) -> FsResult<FsStat>; - async fn stat_async(self: Rc<Self>) -> FsResult<FsStat>; - - fn lock_sync(self: Rc<Self>, exclusive: bool) -> FsResult<()>; - async fn lock_async(self: Rc<Self>, exclusive: bool) -> FsResult<()>; - fn unlock_sync(self: Rc<Self>) -> FsResult<()>; - async fn unlock_async(self: Rc<Self>) -> FsResult<()>; - - fn truncate_sync(self: Rc<Self>, len: u64) -> FsResult<()>; - async fn truncate_async(self: Rc<Self>, len: u64) -> FsResult<()>; - - fn utime_sync( - self: Rc<Self>, - atime_secs: i64, - atime_nanos: u32, - mtime_secs: i64, - mtime_nanos: u32, - ) -> FsResult<()>; - async fn utime_async( - self: Rc<Self>, - atime_secs: i64, - atime_nanos: u32, - mtime_secs: i64, - mtime_nanos: u32, - ) -> FsResult<()>; -} - #[async_trait::async_trait(?Send)] -pub trait FileSystem: Clone { - type File: File; - +pub trait FileSystem: Send + Sync { fn cwd(&self) -> FsResult<PathBuf>; fn tmp_dir(&self) -> FsResult<PathBuf>; - fn chdir(&self, path: impl AsRef<Path>) -> FsResult<()>; + fn chdir(&self, path: &Path) -> FsResult<()>; fn umask(&self, mask: Option<u32>) -> FsResult<u32>; fn open_sync( &self, - path: impl AsRef<Path>, + path: &Path, options: OpenOptions, - ) -> FsResult<Self::File>; + ) -> FsResult<Rc<dyn File>>; async fn open_async( &self, path: PathBuf, options: OpenOptions, - ) -> FsResult<Self::File>; + ) -> FsResult<Rc<dyn File>>; - fn mkdir_sync( - &self, - path: impl AsRef<Path>, - recusive: bool, - mode: u32, - ) -> FsResult<()>; + fn mkdir_sync(&self, path: &Path, recusive: bool, mode: u32) -> FsResult<()>; async fn mkdir_async( &self, path: PathBuf, @@ -184,12 +98,12 @@ pub trait FileSystem: Clone { mode: u32, ) -> FsResult<()>; - fn chmod_sync(&self, path: impl AsRef<Path>, mode: u32) -> FsResult<()>; + fn chmod_sync(&self, path: &Path, mode: u32) -> FsResult<()>; async fn chmod_async(&self, path: PathBuf, mode: u32) -> FsResult<()>; fn chown_sync( &self, - path: impl AsRef<Path>, + path: &Path, uid: Option<u32>, gid: Option<u32>, ) -> FsResult<()>; @@ -200,52 +114,36 @@ pub trait FileSystem: Clone { gid: Option<u32>, ) -> FsResult<()>; - fn remove_sync( - &self, - path: impl AsRef<Path>, - recursive: bool, - ) -> FsResult<()>; + fn remove_sync(&self, path: &Path, recursive: bool) -> FsResult<()>; async fn remove_async(&self, path: PathBuf, recursive: bool) -> FsResult<()>; - fn copy_file_sync( - &self, - oldpath: impl AsRef<Path>, - newpath: impl AsRef<Path>, - ) -> FsResult<()>; + fn copy_file_sync(&self, oldpath: &Path, newpath: &Path) -> FsResult<()>; async fn copy_file_async( &self, oldpath: PathBuf, newpath: PathBuf, ) -> FsResult<()>; - fn stat_sync(&self, path: impl AsRef<Path>) -> FsResult<FsStat>; + fn stat_sync(&self, path: &Path) -> FsResult<FsStat>; async fn stat_async(&self, path: PathBuf) -> FsResult<FsStat>; - fn lstat_sync(&self, path: impl AsRef<Path>) -> FsResult<FsStat>; + fn lstat_sync(&self, path: &Path) -> FsResult<FsStat>; async fn lstat_async(&self, path: PathBuf) -> FsResult<FsStat>; - fn realpath_sync(&self, path: impl AsRef<Path>) -> FsResult<PathBuf>; + fn realpath_sync(&self, path: &Path) -> FsResult<PathBuf>; async fn realpath_async(&self, path: PathBuf) -> FsResult<PathBuf>; - fn read_dir_sync(&self, path: impl AsRef<Path>) -> FsResult<Vec<FsDirEntry>>; + fn read_dir_sync(&self, path: &Path) -> FsResult<Vec<FsDirEntry>>; async fn read_dir_async(&self, path: PathBuf) -> FsResult<Vec<FsDirEntry>>; - fn rename_sync( - &self, - oldpath: impl AsRef<Path>, - newpath: impl AsRef<Path>, - ) -> FsResult<()>; + fn rename_sync(&self, oldpath: &Path, newpath: &Path) -> FsResult<()>; async fn rename_async( &self, oldpath: PathBuf, newpath: PathBuf, ) -> FsResult<()>; - fn link_sync( - &self, - oldpath: impl AsRef<Path>, - newpath: impl AsRef<Path>, - ) -> FsResult<()>; + fn link_sync(&self, oldpath: &Path, newpath: &Path) -> FsResult<()>; async fn link_async( &self, oldpath: PathBuf, @@ -254,8 +152,8 @@ pub trait FileSystem: Clone { fn symlink_sync( &self, - oldpath: impl AsRef<Path>, - newpath: impl AsRef<Path>, + oldpath: &Path, + newpath: &Path, file_type: Option<FsFileType>, ) -> FsResult<()>; async fn symlink_async( @@ -265,15 +163,15 @@ pub trait FileSystem: Clone { file_type: Option<FsFileType>, ) -> FsResult<()>; - fn read_link_sync(&self, path: impl AsRef<Path>) -> FsResult<PathBuf>; + fn read_link_sync(&self, path: &Path) -> FsResult<PathBuf>; async fn read_link_async(&self, path: PathBuf) -> FsResult<PathBuf>; - fn truncate_sync(&self, path: impl AsRef<Path>, len: u64) -> FsResult<()>; + fn truncate_sync(&self, path: &Path, len: u64) -> FsResult<()>; async fn truncate_async(&self, path: PathBuf, len: u64) -> FsResult<()>; fn utime_sync( &self, - path: impl AsRef<Path>, + path: &Path, atime_secs: i64, atime_nanos: u32, mtime_secs: i64, @@ -290,12 +188,11 @@ pub trait FileSystem: Clone { fn write_file_sync( &self, - path: impl AsRef<Path>, + path: &Path, options: OpenOptions, data: &[u8], ) -> FsResult<()> { let file = self.open_sync(path, options)?; - let file = Rc::new(file); if let Some(mode) = options.mode { file.clone().chmod_sync(mode)?; } @@ -309,25 +206,22 @@ pub trait FileSystem: Clone { data: Vec<u8>, ) -> FsResult<()> { let file = self.open_async(path, options).await?; - let file = Rc::new(file); if let Some(mode) = options.mode { file.clone().chmod_async(mode).await?; } - file.write_all_async(data).await?; + file.write_all(data.into()).await?; Ok(()) } - fn read_file_sync(&self, path: impl AsRef<Path>) -> FsResult<Vec<u8>> { + fn read_file_sync(&self, path: &Path) -> FsResult<Vec<u8>> { let options = OpenOptions::read(); let file = self.open_sync(path, options)?; - let file = Rc::new(file); let buf = file.read_all_sync()?; Ok(buf) } async fn read_file_async(&self, path: PathBuf) -> FsResult<Vec<u8>> { let options = OpenOptions::read(); - let file = self.clone().open_async(path, options).await?; - let file = Rc::new(file); + let file = self.open_async(path, options).await?; let buf = file.read_all_async().await?; Ok(buf) } diff --git a/ext/fs/lib.rs b/ext/fs/lib.rs index 464d84ade..4fdf6b3f1 100644 --- a/ext/fs/lib.rs +++ b/ext/fs/lib.rs @@ -4,25 +4,21 @@ mod interface; mod ops; mod std_fs; -pub use crate::interface::File; pub use crate::interface::FileSystem; pub use crate::interface::FsDirEntry; -pub use crate::interface::FsError; pub use crate::interface::FsFileType; -pub use crate::interface::FsResult; -pub use crate::interface::FsStat; pub use crate::interface::OpenOptions; use crate::ops::*; -pub use crate::std_fs::StdFs; +pub use crate::std_fs::RealFs; use deno_core::error::AnyError; use deno_core::OpState; -use deno_core::Resource; use std::cell::RefCell; use std::convert::From; use std::path::Path; use std::rc::Rc; +use std::sync::Arc; pub trait FsPermissions { fn check_read(&mut self, p: &Path, api_name: &str) -> Result<(), AnyError>; @@ -87,78 +83,77 @@ pub(crate) fn check_unstable2(state: &Rc<RefCell<OpState>>, api_name: &str) { deno_core::extension!(deno_fs, deps = [ deno_web ], - parameters = [Fs: FileSystem, P: FsPermissions], - bounds = [Fs::File: Resource], + parameters = [P: FsPermissions], ops = [ - op_cwd<Fs, P>, - op_umask<Fs>, - op_chdir<Fs, P>, + op_cwd<P>, + op_umask, + op_chdir<P>, - op_open_sync<Fs, P>, - op_open_async<Fs, P>, - op_mkdir_sync<Fs, P>, - op_mkdir_async<Fs, P>, - op_chmod_sync<Fs, P>, - op_chmod_async<Fs, P>, - op_chown_sync<Fs, P>, - op_chown_async<Fs, P>, - op_remove_sync<Fs, P>, - op_remove_async<Fs, P>, - op_copy_file_sync<Fs, P>, - op_copy_file_async<Fs, P>, - op_stat_sync<Fs, P>, - op_stat_async<Fs, P>, - op_lstat_sync<Fs, P>, - op_lstat_async<Fs, P>, - op_realpath_sync<Fs, P>, - op_realpath_async<Fs, P>, - op_read_dir_sync<Fs, P>, - op_read_dir_async<Fs, P>, - op_rename_sync<Fs, P>, - op_rename_async<Fs, P>, - op_link_sync<Fs, P>, - op_link_async<Fs, P>, - op_symlink_sync<Fs, P>, - op_symlink_async<Fs, P>, - op_read_link_sync<Fs, P>, - op_read_link_async<Fs, P>, - op_truncate_sync<Fs, P>, - op_truncate_async<Fs, P>, - op_utime_sync<Fs, P>, - op_utime_async<Fs, P>, - op_make_temp_dir_sync<Fs, P>, - op_make_temp_dir_async<Fs, P>, - op_make_temp_file_sync<Fs, P>, - op_make_temp_file_async<Fs, P>, - op_write_file_sync<Fs, P>, - op_write_file_async<Fs, P>, - op_read_file_sync<Fs, P>, - op_read_file_async<Fs, P>, - op_read_file_text_sync<Fs, P>, - op_read_file_text_async<Fs, P>, + op_open_sync<P>, + op_open_async<P>, + op_mkdir_sync<P>, + op_mkdir_async<P>, + op_chmod_sync<P>, + op_chmod_async<P>, + op_chown_sync<P>, + op_chown_async<P>, + op_remove_sync<P>, + op_remove_async<P>, + op_copy_file_sync<P>, + op_copy_file_async<P>, + op_stat_sync<P>, + op_stat_async<P>, + op_lstat_sync<P>, + op_lstat_async<P>, + op_realpath_sync<P>, + op_realpath_async<P>, + op_read_dir_sync<P>, + op_read_dir_async<P>, + op_rename_sync<P>, + op_rename_async<P>, + op_link_sync<P>, + op_link_async<P>, + op_symlink_sync<P>, + op_symlink_async<P>, + op_read_link_sync<P>, + op_read_link_async<P>, + op_truncate_sync<P>, + op_truncate_async<P>, + op_utime_sync<P>, + op_utime_async<P>, + op_make_temp_dir_sync<P>, + op_make_temp_dir_async<P>, + op_make_temp_file_sync<P>, + op_make_temp_file_async<P>, + op_write_file_sync<P>, + op_write_file_async<P>, + op_read_file_sync<P>, + op_read_file_async<P>, + op_read_file_text_sync<P>, + op_read_file_text_async<P>, - op_seek_sync<Fs>, - op_seek_async<Fs>, - op_fdatasync_sync<Fs>, - op_fdatasync_async<Fs>, - op_fsync_sync<Fs>, - op_fsync_async<Fs>, - op_fstat_sync<Fs>, - op_fstat_async<Fs>, - op_flock_sync<Fs>, - op_flock_async<Fs>, - op_funlock_sync<Fs>, - op_funlock_async<Fs>, - op_ftruncate_sync<Fs>, - op_ftruncate_async<Fs>, - op_futime_sync<Fs>, - op_futime_async<Fs>, + op_seek_sync, + op_seek_async, + op_fdatasync_sync, + op_fdatasync_async, + op_fsync_sync, + op_fsync_async, + op_fstat_sync, + op_fstat_async, + op_flock_sync, + op_flock_async, + op_funlock_sync, + op_funlock_async, + op_ftruncate_sync, + op_ftruncate_async, + op_futime_sync, + op_futime_async, ], esm = [ "30_fs.js" ], options = { unstable: bool, - fs: Fs, + fs: Arc<dyn FileSystem>, }, state = |state, options| { state.put(UnstableChecker { unstable: options.unstable }); diff --git a/ext/fs/ops.rs b/ext/fs/ops.rs index 8c5d21201..c9996d8ce 100644 --- a/ext/fs/ops.rs +++ b/ext/fs/ops.rs @@ -7,65 +7,39 @@ use std::io::SeekFrom; use std::path::Path; use std::path::PathBuf; use std::rc::Rc; +use std::sync::Arc; use deno_core::error::custom_error; -use deno_core::error::not_supported; -use deno_core::error::resource_unavailable; use deno_core::error::type_error; use deno_core::error::AnyError; use deno_core::op; use deno_core::CancelFuture; use deno_core::CancelHandle; use deno_core::OpState; -use deno_core::Resource; use deno_core::ResourceId; use deno_core::ZeroCopyBuf; +use deno_io::fs::FileResource; +use deno_io::fs::FsError; +use deno_io::fs::FsStat; use rand::rngs::ThreadRng; use rand::thread_rng; use rand::Rng; use serde::Serialize; -use tokio::task::JoinError; use crate::check_unstable; use crate::check_unstable2; use crate::interface::FsDirEntry; -use crate::interface::FsError; use crate::interface::FsFileType; -use crate::interface::FsStat; -use crate::File; use crate::FileSystem; use crate::FsPermissions; use crate::OpenOptions; -impl From<JoinError> for FsError { - fn from(err: JoinError) -> Self { - if err.is_cancelled() { - todo!("async tasks must not be cancelled") - } - if err.is_panic() { - std::panic::resume_unwind(err.into_panic()); // resume the panic on the main thread - } - unreachable!() - } -} - -impl From<FsError> for AnyError { - fn from(err: FsError) -> Self { - match err { - FsError::Io(err) => AnyError::from(err), - FsError::FileBusy => resource_unavailable(), - FsError::NotSupported => not_supported(), - } - } -} - #[op] -pub fn op_cwd<Fs, P>(state: &mut OpState) -> Result<String, AnyError> +pub fn op_cwd<P>(state: &mut OpState) -> Result<String, AnyError> where - Fs: FileSystem + 'static, P: FsPermissions + 'static, { - let fs = state.borrow::<Fs>(); + let fs = state.borrow::<Arc<dyn FileSystem>>(); let path = fs.cwd()?; state .borrow_mut::<P>() @@ -75,34 +49,36 @@ where } #[op] -fn op_chdir<Fs, P>(state: &mut OpState, directory: &str) -> Result<(), AnyError> +fn op_chdir<P>(state: &mut OpState, directory: &str) -> Result<(), AnyError> where - Fs: FileSystem + 'static, P: FsPermissions + 'static, { let d = PathBuf::from(&directory); state.borrow_mut::<P>().check_read(&d, "Deno.chdir()")?; - state.borrow::<Fs>().chdir(&d).context_path("chdir", &d) + state + .borrow::<Arc<dyn FileSystem>>() + .chdir(&d) + .context_path("chdir", &d) } #[op] -fn op_umask<Fs>(state: &mut OpState, mask: Option<u32>) -> Result<u32, AnyError> +fn op_umask(state: &mut OpState, mask: Option<u32>) -> Result<u32, AnyError> where - Fs: FileSystem + 'static, { check_unstable(state, "Deno.umask"); - state.borrow::<Fs>().umask(mask).context("umask") + state + .borrow::<Arc<dyn FileSystem>>() + .umask(mask) + .context("umask") } #[op] -fn op_open_sync<Fs, P>( +fn op_open_sync<P>( state: &mut OpState, path: String, options: Option<OpenOptions>, ) -> Result<ResourceId, AnyError> where - Fs: FileSystem + 'static, - Fs::File: Resource, P: FsPermissions + 'static, { let path = PathBuf::from(path); @@ -111,22 +87,22 @@ where let permissions = state.borrow_mut::<P>(); permissions.check(&options, &path, "Deno.openSync()")?; - let fs = state.borrow::<Fs>(); + let fs = state.borrow::<Arc<dyn FileSystem>>(); let file = fs.open_sync(&path, options).context_path("open", &path)?; - let rid = state.resource_table.add(file); + let rid = state + .resource_table + .add(FileResource::new(file, "fsFile".to_string())); Ok(rid) } #[op] -async fn op_open_async<Fs, P>( +async fn op_open_async<P>( state: Rc<RefCell<OpState>>, path: String, options: Option<OpenOptions>, ) -> Result<ResourceId, AnyError> where - Fs: FileSystem + 'static, - Fs::File: Resource, P: FsPermissions + 'static, { let path = PathBuf::from(path); @@ -136,26 +112,28 @@ where let mut state = state.borrow_mut(); let permissions = state.borrow_mut::<P>(); permissions.check(&options, &path, "Deno.open()")?; - state.borrow::<Fs>().clone() + state.borrow::<Arc<dyn FileSystem>>().clone() }; let file = fs .open_async(path.clone(), options) .await .context_path("open", &path)?; - let rid = state.borrow_mut().resource_table.add(file); + let rid = state + .borrow_mut() + .resource_table + .add(FileResource::new(file, "fsFile".to_string())); Ok(rid) } #[op] -fn op_mkdir_sync<Fs, P>( +fn op_mkdir_sync<P>( state: &mut OpState, path: String, recursive: bool, mode: Option<u32>, ) -> Result<(), AnyError> where - Fs: FileSystem + 'static, P: FsPermissions + 'static, { let path = PathBuf::from(path); @@ -166,7 +144,7 @@ where .borrow_mut::<P>() .check_write(&path, "Deno.mkdirSync()")?; - let fs = state.borrow::<Fs>(); + let fs = state.borrow::<Arc<dyn FileSystem>>(); fs.mkdir_sync(&path, recursive, mode) .context_path("mkdir", &path)?; @@ -174,14 +152,13 @@ where } #[op] -async fn op_mkdir_async<Fs, P>( +async fn op_mkdir_async<P>( state: Rc<RefCell<OpState>>, path: String, recursive: bool, mode: Option<u32>, ) -> Result<(), AnyError> where - Fs: FileSystem + 'static, P: FsPermissions + 'static, { let path = PathBuf::from(path); @@ -191,7 +168,7 @@ where let fs = { let mut state = state.borrow_mut(); state.borrow_mut::<P>().check_write(&path, "Deno.mkdir()")?; - state.borrow::<Fs>().clone() + state.borrow::<Arc<dyn FileSystem>>().clone() }; fs.mkdir_async(path.clone(), recursive, mode) @@ -202,39 +179,37 @@ where } #[op] -fn op_chmod_sync<Fs, P>( +fn op_chmod_sync<P>( state: &mut OpState, path: String, mode: u32, ) -> Result<(), AnyError> where - Fs: FileSystem + 'static, P: FsPermissions + 'static, { let path = PathBuf::from(path); state .borrow_mut::<P>() .check_write(&path, "Deno.chmodSync()")?; - let fs = state.borrow::<Fs>(); + let fs = state.borrow::<Arc<dyn FileSystem>>(); fs.chmod_sync(&path, mode).context_path("chmod", &path)?; Ok(()) } #[op] -async fn op_chmod_async<Fs, P>( +async fn op_chmod_async<P>( state: Rc<RefCell<OpState>>, path: String, mode: u32, ) -> Result<(), AnyError> where - Fs: FileSystem + 'static, P: FsPermissions + 'static, { let path = PathBuf::from(path); let fs = { let mut state = state.borrow_mut(); state.borrow_mut::<P>().check_write(&path, "Deno.chmod()")?; - state.borrow::<Fs>().clone() + state.borrow::<Arc<dyn FileSystem>>().clone() }; fs.chmod_async(path.clone(), mode) .await @@ -243,42 +218,40 @@ where } #[op] -fn op_chown_sync<Fs, P>( +fn op_chown_sync<P>( state: &mut OpState, path: String, uid: Option<u32>, gid: Option<u32>, ) -> Result<(), AnyError> where - Fs: FileSystem + 'static, P: FsPermissions + 'static, { let path = PathBuf::from(path); state .borrow_mut::<P>() .check_write(&path, "Deno.chownSync()")?; - let fs = state.borrow::<Fs>(); + let fs = state.borrow::<Arc<dyn FileSystem>>(); fs.chown_sync(&path, uid, gid) .context_path("chown", &path)?; Ok(()) } #[op] -async fn op_chown_async<Fs, P>( +async fn op_chown_async<P>( state: Rc<RefCell<OpState>>, path: String, uid: Option<u32>, gid: Option<u32>, ) -> Result<(), AnyError> where - Fs: FileSystem + 'static, P: FsPermissions + 'static, { let path = PathBuf::from(path); let fs = { let mut state = state.borrow_mut(); state.borrow_mut::<P>().check_write(&path, "Deno.chown()")?; - state.borrow::<Fs>().clone() + state.borrow::<Arc<dyn FileSystem>>().clone() }; fs.chown_async(path.clone(), uid, gid) .await @@ -287,13 +260,12 @@ where } #[op] -fn op_remove_sync<Fs, P>( +fn op_remove_sync<P>( state: &mut OpState, path: &str, recursive: bool, ) -> Result<(), AnyError> where - Fs: FileSystem + 'static, P: FsPermissions + 'static, { let path = PathBuf::from(path); @@ -302,7 +274,7 @@ where .borrow_mut::<P>() .check_write(&path, "Deno.removeSync()")?; - let fs = state.borrow::<Fs>(); + let fs = state.borrow::<Arc<dyn FileSystem>>(); fs.remove_sync(&path, recursive) .context_path("remove", &path)?; @@ -310,13 +282,12 @@ where } #[op] -async fn op_remove_async<Fs, P>( +async fn op_remove_async<P>( state: Rc<RefCell<OpState>>, path: String, recursive: bool, ) -> Result<(), AnyError> where - Fs: FileSystem + 'static, P: FsPermissions + 'static, { let path = PathBuf::from(path); @@ -326,7 +297,7 @@ where state .borrow_mut::<P>() .check_write(&path, "Deno.remove()")?; - state.borrow::<Fs>().clone() + state.borrow::<Arc<dyn FileSystem>>().clone() }; fs.remove_async(path.clone(), recursive) @@ -337,13 +308,12 @@ where } #[op] -fn op_copy_file_sync<Fs, P>( +fn op_copy_file_sync<P>( state: &mut OpState, from: &str, to: &str, ) -> Result<(), AnyError> where - Fs: FileSystem + 'static, P: FsPermissions + 'static, { let from = PathBuf::from(from); @@ -353,7 +323,7 @@ where permissions.check_read(&from, "Deno.copyFileSync()")?; permissions.check_write(&to, "Deno.copyFileSync()")?; - let fs = state.borrow::<Fs>(); + let fs = state.borrow::<Arc<dyn FileSystem>>(); fs.copy_file_sync(&from, &to) .context_two_path("copy", &from, &to)?; @@ -361,13 +331,12 @@ where } #[op] -async fn op_copy_file_async<Fs, P>( +async fn op_copy_file_async<P>( state: Rc<RefCell<OpState>>, from: String, to: String, ) -> Result<(), AnyError> where - Fs: FileSystem + 'static, P: FsPermissions + 'static, { let from = PathBuf::from(from); @@ -378,7 +347,7 @@ where let permissions = state.borrow_mut::<P>(); permissions.check_read(&from, "Deno.copyFile()")?; permissions.check_write(&to, "Deno.copyFile()")?; - state.borrow::<Fs>().clone() + state.borrow::<Arc<dyn FileSystem>>().clone() }; fs.copy_file_async(from.clone(), to.clone()) @@ -389,20 +358,19 @@ where } #[op] -fn op_stat_sync<Fs, P>( +fn op_stat_sync<P>( state: &mut OpState, path: String, stat_out_buf: &mut [u32], ) -> Result<(), AnyError> where - Fs: FileSystem + 'static, P: FsPermissions + 'static, { let path = PathBuf::from(path); state .borrow_mut::<P>() .check_read(&path, "Deno.statSync()")?; - let fs = state.borrow::<Fs>(); + let fs = state.borrow::<Arc<dyn FileSystem>>(); let stat = fs.stat_sync(&path).context_path("stat", &path)?; let serializable_stat = SerializableStat::from(stat); serializable_stat.write(stat_out_buf); @@ -410,12 +378,11 @@ where } #[op] -async fn op_stat_async<Fs, P>( +async fn op_stat_async<P>( state: Rc<RefCell<OpState>>, path: String, ) -> Result<SerializableStat, AnyError> where - Fs: FileSystem + 'static, P: FsPermissions + 'static, { let path = PathBuf::from(path); @@ -423,7 +390,7 @@ where let mut state = state.borrow_mut(); let permissions = state.borrow_mut::<P>(); permissions.check_read(&path, "Deno.stat()")?; - state.borrow::<Fs>().clone() + state.borrow::<Arc<dyn FileSystem>>().clone() }; let stat = fs .stat_async(path.clone()) @@ -433,20 +400,19 @@ where } #[op] -fn op_lstat_sync<Fs, P>( +fn op_lstat_sync<P>( state: &mut OpState, path: String, stat_out_buf: &mut [u32], ) -> Result<(), AnyError> where - Fs: FileSystem + 'static, P: FsPermissions + 'static, { let path = PathBuf::from(path); state .borrow_mut::<P>() .check_read(&path, "Deno.lstatSync()")?; - let fs = state.borrow::<Fs>(); + let fs = state.borrow::<Arc<dyn FileSystem>>(); let stat = fs.lstat_sync(&path).context_path("lstat", &path)?; let serializable_stat = SerializableStat::from(stat); serializable_stat.write(stat_out_buf); @@ -454,12 +420,11 @@ where } #[op] -async fn op_lstat_async<Fs, P>( +async fn op_lstat_async<P>( state: Rc<RefCell<OpState>>, path: String, ) -> Result<SerializableStat, AnyError> where - Fs: FileSystem + 'static, P: FsPermissions + 'static, { let path = PathBuf::from(path); @@ -467,7 +432,7 @@ where let mut state = state.borrow_mut(); let permissions = state.borrow_mut::<P>(); permissions.check_read(&path, "Deno.lstat()")?; - state.borrow::<Fs>().clone() + state.borrow::<Arc<dyn FileSystem>>().clone() }; let stat = fs .lstat_async(path.clone()) @@ -477,17 +442,16 @@ where } #[op] -fn op_realpath_sync<Fs, P>( +fn op_realpath_sync<P>( state: &mut OpState, path: String, ) -> Result<String, AnyError> where - Fs: FileSystem + 'static, P: FsPermissions + 'static, { let path = PathBuf::from(path); - let fs = state.borrow::<Fs>().clone(); + let fs = state.borrow::<Arc<dyn FileSystem>>().clone(); let permissions = state.borrow_mut::<P>(); permissions.check_read(&path, "Deno.realPathSync()")?; if path.is_relative() { @@ -502,12 +466,11 @@ where } #[op] -async fn op_realpath_async<Fs, P>( +async fn op_realpath_async<P>( state: Rc<RefCell<OpState>>, path: String, ) -> Result<String, AnyError> where - Fs: FileSystem + 'static, P: FsPermissions + 'static, { let path = PathBuf::from(path); @@ -515,7 +478,7 @@ where let fs; { let mut state = state.borrow_mut(); - fs = state.borrow::<Fs>().clone(); + fs = state.borrow::<Arc<dyn FileSystem>>().clone(); let permissions = state.borrow_mut::<P>(); permissions.check_read(&path, "Deno.realPath()")?; if path.is_relative() { @@ -532,12 +495,11 @@ where } #[op] -fn op_read_dir_sync<Fs, P>( +fn op_read_dir_sync<P>( state: &mut OpState, path: String, ) -> Result<Vec<FsDirEntry>, AnyError> where - Fs: FileSystem + 'static, P: FsPermissions + 'static, { let path = PathBuf::from(path); @@ -546,19 +508,18 @@ where .borrow_mut::<P>() .check_read(&path, "Deno.readDirSync()")?; - let fs = state.borrow::<Fs>(); + let fs = state.borrow::<Arc<dyn FileSystem>>(); let entries = fs.read_dir_sync(&path).context_path("readdir", &path)?; Ok(entries) } #[op] -async fn op_read_dir_async<Fs, P>( +async fn op_read_dir_async<P>( state: Rc<RefCell<OpState>>, path: String, ) -> Result<Vec<FsDirEntry>, AnyError> where - Fs: FileSystem + 'static, P: FsPermissions + 'static, { let path = PathBuf::from(path); @@ -568,7 +529,7 @@ where state .borrow_mut::<P>() .check_read(&path, "Deno.readDir()")?; - state.borrow::<Fs>().clone() + state.borrow::<Arc<dyn FileSystem>>().clone() }; let entries = fs @@ -580,13 +541,12 @@ where } #[op] -fn op_rename_sync<Fs, P>( +fn op_rename_sync<P>( state: &mut OpState, oldpath: String, newpath: String, ) -> Result<(), AnyError> where - Fs: FileSystem + 'static, P: FsPermissions + 'static, { let oldpath = PathBuf::from(oldpath); @@ -597,7 +557,7 @@ where permissions.check_write(&oldpath, "Deno.renameSync()")?; permissions.check_write(&newpath, "Deno.renameSync()")?; - let fs = state.borrow::<Fs>(); + let fs = state.borrow::<Arc<dyn FileSystem>>(); fs.rename_sync(&oldpath, &newpath) .context_two_path("rename", &oldpath, &newpath)?; @@ -605,13 +565,12 @@ where } #[op] -async fn op_rename_async<Fs, P>( +async fn op_rename_async<P>( state: Rc<RefCell<OpState>>, oldpath: String, newpath: String, ) -> Result<(), AnyError> where - Fs: FileSystem + 'static, P: FsPermissions + 'static, { let oldpath = PathBuf::from(oldpath); @@ -623,7 +582,7 @@ where permissions.check_read(&oldpath, "Deno.rename()")?; permissions.check_write(&oldpath, "Deno.rename()")?; permissions.check_write(&newpath, "Deno.rename()")?; - state.borrow::<Fs>().clone() + state.borrow::<Arc<dyn FileSystem>>().clone() }; fs.rename_async(oldpath.clone(), newpath.clone()) @@ -634,13 +593,12 @@ where } #[op] -fn op_link_sync<Fs, P>( +fn op_link_sync<P>( state: &mut OpState, oldpath: &str, newpath: &str, ) -> Result<(), AnyError> where - Fs: FileSystem + 'static, P: FsPermissions + 'static, { let oldpath = PathBuf::from(oldpath); @@ -652,7 +610,7 @@ where permissions.check_read(&newpath, "Deno.linkSync()")?; permissions.check_write(&newpath, "Deno.linkSync()")?; - let fs = state.borrow::<Fs>(); + let fs = state.borrow::<Arc<dyn FileSystem>>(); fs.link_sync(&oldpath, &newpath) .context_two_path("link", &oldpath, &newpath)?; @@ -660,13 +618,12 @@ where } #[op] -async fn op_link_async<Fs, P>( +async fn op_link_async<P>( state: Rc<RefCell<OpState>>, oldpath: String, newpath: String, ) -> Result<(), AnyError> where - Fs: FileSystem + 'static, P: FsPermissions + 'static, { let oldpath = PathBuf::from(&oldpath); @@ -679,7 +636,7 @@ where permissions.check_write(&oldpath, "Deno.link()")?; permissions.check_read(&newpath, "Deno.link()")?; permissions.check_write(&newpath, "Deno.link()")?; - state.borrow::<Fs>().clone() + state.borrow::<Arc<dyn FileSystem>>().clone() }; fs.link_async(oldpath.clone(), newpath.clone()) @@ -690,14 +647,13 @@ where } #[op] -fn op_symlink_sync<Fs, P>( +fn op_symlink_sync<P>( state: &mut OpState, oldpath: &str, newpath: &str, file_type: Option<FsFileType>, ) -> Result<(), AnyError> where - Fs: FileSystem + 'static, P: FsPermissions + 'static, { let oldpath = PathBuf::from(oldpath); @@ -707,7 +663,7 @@ where permissions.check_write_all("Deno.symlinkSync()")?; permissions.check_read_all("Deno.symlinkSync()")?; - let fs = state.borrow::<Fs>(); + let fs = state.borrow::<Arc<dyn FileSystem>>(); fs.symlink_sync(&oldpath, &newpath, file_type) .context_two_path("symlink", &oldpath, &newpath)?; @@ -715,14 +671,13 @@ where } #[op] -async fn op_symlink_async<Fs, P>( +async fn op_symlink_async<P>( state: Rc<RefCell<OpState>>, oldpath: String, newpath: String, file_type: Option<FsFileType>, ) -> Result<(), AnyError> where - Fs: FileSystem + 'static, P: FsPermissions + 'static, { let oldpath = PathBuf::from(&oldpath); @@ -733,7 +688,7 @@ where let permissions = state.borrow_mut::<P>(); permissions.check_write_all("Deno.symlink()")?; permissions.check_read_all("Deno.symlink()")?; - state.borrow::<Fs>().clone() + state.borrow::<Arc<dyn FileSystem>>().clone() }; fs.symlink_async(oldpath.clone(), newpath.clone(), file_type) @@ -744,12 +699,11 @@ where } #[op] -fn op_read_link_sync<Fs, P>( +fn op_read_link_sync<P>( state: &mut OpState, path: String, ) -> Result<String, AnyError> where - Fs: FileSystem + 'static, P: FsPermissions + 'static, { let path = PathBuf::from(path); @@ -758,7 +712,7 @@ where .borrow_mut::<P>() .check_read(&path, "Deno.readLink()")?; - let fs = state.borrow::<Fs>(); + let fs = state.borrow::<Arc<dyn FileSystem>>(); let target = fs.read_link_sync(&path).context_path("readlink", &path)?; let target_string = path_into_string(target.into_os_string())?; @@ -766,12 +720,11 @@ where } #[op] -async fn op_read_link_async<Fs, P>( +async fn op_read_link_async<P>( state: Rc<RefCell<OpState>>, path: String, ) -> Result<String, AnyError> where - Fs: FileSystem + 'static, P: FsPermissions + 'static, { let path = PathBuf::from(path); @@ -781,7 +734,7 @@ where state .borrow_mut::<P>() .check_read(&path, "Deno.readLink()")?; - state.borrow::<Fs>().clone() + state.borrow::<Arc<dyn FileSystem>>().clone() }; let target = fs @@ -793,13 +746,12 @@ where } #[op] -fn op_truncate_sync<Fs, P>( +fn op_truncate_sync<P>( state: &mut OpState, path: &str, len: u64, ) -> Result<(), AnyError> where - Fs: FileSystem + 'static, P: FsPermissions + 'static, { let path = PathBuf::from(path); @@ -808,7 +760,7 @@ where .borrow_mut::<P>() .check_write(&path, "Deno.truncateSync()")?; - let fs = state.borrow::<Fs>(); + let fs = state.borrow::<Arc<dyn FileSystem>>(); fs.truncate_sync(&path, len) .context_path("truncate", &path)?; @@ -816,13 +768,12 @@ where } #[op] -async fn op_truncate_async<Fs, P>( +async fn op_truncate_async<P>( state: Rc<RefCell<OpState>>, path: String, len: u64, ) -> Result<(), AnyError> where - Fs: FileSystem + 'static, P: FsPermissions + 'static, { let path = PathBuf::from(path); @@ -832,7 +783,7 @@ where state .borrow_mut::<P>() .check_write(&path, "Deno.truncate()")?; - state.borrow::<Fs>().clone() + state.borrow::<Arc<dyn FileSystem>>().clone() }; fs.truncate_async(path.clone(), len) @@ -843,7 +794,7 @@ where } #[op] -fn op_utime_sync<Fs, P>( +fn op_utime_sync<P>( state: &mut OpState, path: &str, atime_secs: i64, @@ -852,14 +803,13 @@ fn op_utime_sync<Fs, P>( mtime_nanos: u32, ) -> Result<(), AnyError> where - Fs: FileSystem + 'static, P: FsPermissions + 'static, { let path = PathBuf::from(path); state.borrow_mut::<P>().check_write(&path, "Deno.utime()")?; - let fs = state.borrow::<Fs>(); + let fs = state.borrow::<Arc<dyn FileSystem>>(); fs.utime_sync(&path, atime_secs, atime_nanos, mtime_secs, mtime_nanos) .context_path("utime", &path)?; @@ -867,7 +817,7 @@ where } #[op] -async fn op_utime_async<Fs, P>( +async fn op_utime_async<P>( state: Rc<RefCell<OpState>>, path: String, atime_secs: i64, @@ -876,7 +826,6 @@ async fn op_utime_async<Fs, P>( mtime_nanos: u32, ) -> Result<(), AnyError> where - Fs: FileSystem + 'static, P: FsPermissions + 'static, { let path = PathBuf::from(path); @@ -884,7 +833,7 @@ where let fs = { let mut state = state.borrow_mut(); state.borrow_mut::<P>().check_write(&path, "Deno.utime()")?; - state.borrow::<Fs>().clone() + state.borrow::<Arc<dyn FileSystem>>().clone() }; fs.utime_async( @@ -901,17 +850,16 @@ where } #[op] -fn op_make_temp_dir_sync<Fs, P>( +fn op_make_temp_dir_sync<P>( state: &mut OpState, dir: Option<String>, prefix: Option<String>, suffix: Option<String>, ) -> Result<String, AnyError> where - Fs: FileSystem + 'static, P: FsPermissions + 'static, { - let (dir, fs) = make_temp_check_sync::<Fs, P>(state, dir)?; + let (dir, fs) = make_temp_check_sync::<P>(state, dir)?; let mut rng = thread_rng(); @@ -935,17 +883,16 @@ where } #[op] -async fn op_make_temp_dir_async<Fs, P>( +async fn op_make_temp_dir_async<P>( state: Rc<RefCell<OpState>>, dir: Option<String>, prefix: Option<String>, suffix: Option<String>, ) -> Result<String, AnyError> where - Fs: FileSystem + 'static, P: FsPermissions + 'static, { - let (dir, fs) = make_temp_check_async::<Fs, P>(state, dir)?; + let (dir, fs) = make_temp_check_async::<P>(state, dir)?; let mut rng = thread_rng(); @@ -969,17 +916,16 @@ where } #[op] -fn op_make_temp_file_sync<Fs, P>( +fn op_make_temp_file_sync<P>( state: &mut OpState, dir: Option<String>, prefix: Option<String>, suffix: Option<String>, ) -> Result<String, AnyError> where - Fs: FileSystem + 'static, P: FsPermissions + 'static, { - let (dir, fs) = make_temp_check_sync::<Fs, P>(state, dir)?; + let (dir, fs) = make_temp_check_sync::<P>(state, dir)?; let open_opts = OpenOptions { write: true, @@ -1010,17 +956,16 @@ where } #[op] -async fn op_make_temp_file_async<Fs, P>( +async fn op_make_temp_file_async<P>( state: Rc<RefCell<OpState>>, dir: Option<String>, prefix: Option<String>, suffix: Option<String>, ) -> Result<String, AnyError> where - Fs: FileSystem + 'static, P: FsPermissions + 'static, { - let (dir, fs) = make_temp_check_async::<Fs, P>(state, dir)?; + let (dir, fs) = make_temp_check_async::<P>(state, dir)?; let open_opts = OpenOptions { write: true, @@ -1049,15 +994,14 @@ where .context("tmpfile") } -fn make_temp_check_sync<Fs, P>( +fn make_temp_check_sync<P>( state: &mut OpState, dir: Option<String>, -) -> Result<(PathBuf, Fs), AnyError> +) -> Result<(PathBuf, Arc<dyn FileSystem>), AnyError> where - Fs: FileSystem + 'static, P: FsPermissions + 'static, { - let fs = state.borrow::<Fs>().clone(); + let fs = state.borrow::<Arc<dyn FileSystem>>().clone(); let dir = match dir { Some(dir) => { let dir = PathBuf::from(dir); @@ -1079,16 +1023,15 @@ where Ok((dir, fs)) } -fn make_temp_check_async<Fs, P>( +fn make_temp_check_async<P>( state: Rc<RefCell<OpState>>, dir: Option<String>, -) -> Result<(PathBuf, Fs), AnyError> +) -> Result<(PathBuf, Arc<dyn FileSystem>), AnyError> where - Fs: FileSystem + 'static, P: FsPermissions + 'static, { let mut state = state.borrow_mut(); - let fs = state.borrow::<Fs>().clone(); + let fs = state.borrow::<Arc<dyn FileSystem>>().clone(); let dir = match dir { Some(dir) => { let dir = PathBuf::from(dir); @@ -1128,7 +1071,7 @@ fn tmp_name( } #[op] -fn op_write_file_sync<Fs, P>( +fn op_write_file_sync<P>( state: &mut OpState, path: String, mode: Option<u32>, @@ -1138,7 +1081,6 @@ fn op_write_file_sync<Fs, P>( data: ZeroCopyBuf, ) -> Result<(), AnyError> where - Fs: FileSystem + 'static, P: FsPermissions + 'static, { let path = PathBuf::from(path); @@ -1147,7 +1089,7 @@ where let options = OpenOptions::write(create, append, create_new, mode); permissions.check(&options, &path, "Deno.writeFileSync()")?; - let fs = state.borrow::<Fs>(); + let fs = state.borrow::<Arc<dyn FileSystem>>(); fs.write_file_sync(&path, options, &data) .context_path("writefile", &path)?; @@ -1156,7 +1098,7 @@ where } #[op] -async fn op_write_file_async<Fs, P>( +async fn op_write_file_async<P>( state: Rc<RefCell<OpState>>, path: String, mode: Option<u32>, @@ -1167,7 +1109,6 @@ async fn op_write_file_async<Fs, P>( cancel_rid: Option<ResourceId>, ) -> Result<(), AnyError> where - Fs: FileSystem + 'static, P: FsPermissions + 'static, { let path = PathBuf::from(path); @@ -1180,7 +1121,7 @@ where permissions.check(&options, &path, "Deno.writeFile()")?; let cancel_handle = cancel_rid .and_then(|rid| state.resource_table.get::<CancelHandle>(rid).ok()); - (state.borrow::<Fs>().clone(), cancel_handle) + (state.borrow::<Arc<dyn FileSystem>>().clone(), cancel_handle) }; let fut = fs.write_file_async(path.clone(), options, data.to_vec()); @@ -1201,12 +1142,11 @@ where } #[op] -fn op_read_file_sync<Fs, P>( +fn op_read_file_sync<P>( state: &mut OpState, path: String, ) -> Result<ZeroCopyBuf, AnyError> where - Fs: FileSystem + 'static, P: FsPermissions + 'static, { let path = PathBuf::from(path); @@ -1214,20 +1154,19 @@ where let permissions = state.borrow_mut::<P>(); permissions.check_read(&path, "Deno.readFileSync()")?; - let fs = state.borrow::<Fs>(); - let buf = fs.read_file_sync(path).context("readfile")?; + let fs = state.borrow::<Arc<dyn FileSystem>>(); + let buf = fs.read_file_sync(&path).context("readfile")?; Ok(buf.into()) } #[op] -async fn op_read_file_async<Fs, P>( +async fn op_read_file_async<P>( state: Rc<RefCell<OpState>>, path: String, cancel_rid: Option<ResourceId>, ) -> Result<ZeroCopyBuf, AnyError> where - Fs: FileSystem + 'static, P: FsPermissions + 'static, { let path = PathBuf::from(path); @@ -1238,7 +1177,7 @@ where permissions.check_read(&path, "Deno.readFile()")?; let cancel_handle = cancel_rid .and_then(|rid| state.resource_table.get::<CancelHandle>(rid).ok()); - (state.borrow::<Fs>().clone(), cancel_handle) + (state.borrow::<Arc<dyn FileSystem>>().clone(), cancel_handle) }; let fut = fs.read_file_async(path.clone()); @@ -1259,12 +1198,11 @@ where } #[op] -fn op_read_file_text_sync<Fs, P>( +fn op_read_file_text_sync<P>( state: &mut OpState, path: String, ) -> Result<String, AnyError> where - Fs: FileSystem + 'static, P: FsPermissions + 'static, { let path = PathBuf::from(path); @@ -1272,20 +1210,19 @@ where let permissions = state.borrow_mut::<P>(); permissions.check_read(&path, "Deno.readFileSync()")?; - let fs = state.borrow::<Fs>(); - let buf = fs.read_file_sync(path).context("readfile")?; + let fs = state.borrow::<Arc<dyn FileSystem>>(); + let buf = fs.read_file_sync(&path).context("readfile")?; Ok(string_from_utf8_lossy(buf)) } #[op] -async fn op_read_file_text_async<Fs, P>( +async fn op_read_file_text_async<P>( state: Rc<RefCell<OpState>>, path: String, cancel_rid: Option<ResourceId>, ) -> Result<String, AnyError> where - Fs: FileSystem + 'static, P: FsPermissions + 'static, { let path = PathBuf::from(path); @@ -1296,7 +1233,7 @@ where permissions.check_read(&path, "Deno.readFile()")?; let cancel_handle = cancel_rid .and_then(|rid| state.resource_table.get::<CancelHandle>(rid).ok()); - (state.borrow::<Fs>().clone(), cancel_handle) + (state.borrow::<Arc<dyn FileSystem>>().clone(), cancel_handle) }; let fut = fs.read_file_async(path.clone()); @@ -1340,106 +1277,75 @@ fn to_seek_from(offset: i64, whence: i32) -> Result<SeekFrom, AnyError> { } #[op] -fn op_seek_sync<Fs>( +fn op_seek_sync( state: &mut OpState, rid: ResourceId, offset: i64, whence: i32, -) -> Result<u64, AnyError> -where - Fs: FileSystem + 'static, - Fs::File: Resource, -{ +) -> Result<u64, AnyError> { let pos = to_seek_from(offset, whence)?; - let file = state.resource_table.get::<Fs::File>(rid)?; + let file = FileResource::get_file(state, rid)?; let cursor = file.seek_sync(pos)?; Ok(cursor) } #[op] -async fn op_seek_async<Fs>( +async fn op_seek_async( state: Rc<RefCell<OpState>>, rid: ResourceId, offset: i64, whence: i32, -) -> Result<u64, AnyError> -where - Fs: FileSystem + 'static, - Fs::File: Resource, -{ +) -> Result<u64, AnyError> { let pos = to_seek_from(offset, whence)?; - let file = state.borrow().resource_table.get::<Fs::File>(rid)?; + let file = FileResource::get_file(&state.borrow(), rid)?; let cursor = file.seek_async(pos).await?; Ok(cursor) } #[op] -fn op_fdatasync_sync<Fs>( +fn op_fdatasync_sync( state: &mut OpState, rid: ResourceId, -) -> Result<(), AnyError> -where - Fs: FileSystem + 'static, - Fs::File: Resource, -{ - let file = state.resource_table.get::<Fs::File>(rid)?; +) -> Result<(), AnyError> { + let file = FileResource::get_file(state, rid)?; file.datasync_sync()?; Ok(()) } #[op] -async fn op_fdatasync_async<Fs>( +async fn op_fdatasync_async( state: Rc<RefCell<OpState>>, rid: ResourceId, -) -> Result<(), AnyError> -where - Fs: FileSystem + 'static, - Fs::File: Resource, -{ - let file = state.borrow().resource_table.get::<Fs::File>(rid)?; +) -> Result<(), AnyError> { + let file = FileResource::get_file(&state.borrow(), rid)?; file.datasync_async().await?; Ok(()) } #[op] -fn op_fsync_sync<Fs>( - state: &mut OpState, - rid: ResourceId, -) -> Result<(), AnyError> -where - Fs: FileSystem + 'static, - Fs::File: Resource, -{ - let file = state.resource_table.get::<Fs::File>(rid)?; +fn op_fsync_sync(state: &mut OpState, rid: ResourceId) -> Result<(), AnyError> { + let file = FileResource::get_file(state, rid)?; file.sync_sync()?; Ok(()) } #[op] -async fn op_fsync_async<Fs>( +async fn op_fsync_async( state: Rc<RefCell<OpState>>, rid: ResourceId, -) -> Result<(), AnyError> -where - Fs: FileSystem + 'static, - Fs::File: Resource, -{ - let file = state.borrow().resource_table.get::<Fs::File>(rid)?; +) -> Result<(), AnyError> { + let file = FileResource::get_file(&state.borrow(), rid)?; file.sync_async().await?; Ok(()) } #[op] -fn op_fstat_sync<Fs>( +fn op_fstat_sync( state: &mut OpState, rid: ResourceId, stat_out_buf: &mut [u32], -) -> Result<(), AnyError> -where - Fs: FileSystem + 'static, - Fs::File: Resource, -{ - let file = state.resource_table.get::<Fs::File>(rid)?; +) -> Result<(), AnyError> { + let file = FileResource::get_file(state, rid)?; let stat = file.stat_sync()?; let serializable_stat = SerializableStat::from(stat); serializable_stat.write(stat_out_buf); @@ -1447,143 +1353,107 @@ where } #[op] -async fn op_fstat_async<Fs>( +async fn op_fstat_async( state: Rc<RefCell<OpState>>, rid: ResourceId, -) -> Result<SerializableStat, AnyError> -where - Fs: FileSystem + 'static, - Fs::File: Resource, -{ - let file = state.borrow().resource_table.get::<Fs::File>(rid)?; +) -> Result<SerializableStat, AnyError> { + let file = FileResource::get_file(&state.borrow(), rid)?; let stat = file.stat_async().await?; Ok(stat.into()) } #[op] -fn op_flock_sync<Fs>( +fn op_flock_sync( state: &mut OpState, rid: ResourceId, exclusive: bool, -) -> Result<(), AnyError> -where - Fs: FileSystem + 'static, - Fs::File: Resource, -{ +) -> Result<(), AnyError> { check_unstable(state, "Deno.flockSync"); - let file = state.resource_table.get::<Fs::File>(rid)?; + let file = FileResource::get_file(state, rid)?; file.lock_sync(exclusive)?; Ok(()) } #[op] -async fn op_flock_async<Fs>( +async fn op_flock_async( state: Rc<RefCell<OpState>>, rid: ResourceId, exclusive: bool, -) -> Result<(), AnyError> -where - Fs: FileSystem + 'static, - Fs::File: Resource, -{ +) -> Result<(), AnyError> { check_unstable2(&state, "Deno.flock"); - let file = state.borrow().resource_table.get::<Fs::File>(rid)?; + let file = FileResource::get_file(&state.borrow(), rid)?; file.lock_async(exclusive).await?; Ok(()) } #[op] -fn op_funlock_sync<Fs>( +fn op_funlock_sync( state: &mut OpState, rid: ResourceId, -) -> Result<(), AnyError> -where - Fs: FileSystem + 'static, - Fs::File: Resource, -{ +) -> Result<(), AnyError> { check_unstable(state, "Deno.funlockSync"); - let file = state.resource_table.get::<Fs::File>(rid)?; + let file = FileResource::get_file(state, rid)?; file.unlock_sync()?; Ok(()) } #[op] -async fn op_funlock_async<Fs>( +async fn op_funlock_async( state: Rc<RefCell<OpState>>, rid: ResourceId, -) -> Result<(), AnyError> -where - Fs: FileSystem + 'static, - Fs::File: Resource, -{ +) -> Result<(), AnyError> { check_unstable2(&state, "Deno.funlock"); - let file = state.borrow().resource_table.get::<Fs::File>(rid)?; + let file = FileResource::get_file(&state.borrow(), rid)?; file.unlock_async().await?; Ok(()) } #[op] -fn op_ftruncate_sync<Fs>( +fn op_ftruncate_sync( state: &mut OpState, rid: ResourceId, len: u64, -) -> Result<(), AnyError> -where - Fs: FileSystem + 'static, - Fs::File: Resource, -{ - let file = state.resource_table.get::<Fs::File>(rid)?; +) -> Result<(), AnyError> { + let file = FileResource::get_file(state, rid)?; file.truncate_sync(len)?; Ok(()) } #[op] -async fn op_ftruncate_async<Fs>( +async fn op_ftruncate_async( state: Rc<RefCell<OpState>>, rid: ResourceId, len: u64, -) -> Result<(), AnyError> -where - Fs: FileSystem + 'static, - Fs::File: Resource, -{ - let file = state.borrow().resource_table.get::<Fs::File>(rid)?; +) -> Result<(), AnyError> { + let file = FileResource::get_file(&state.borrow(), rid)?; file.truncate_async(len).await?; Ok(()) } #[op] -fn op_futime_sync<Fs>( +fn op_futime_sync( state: &mut OpState, rid: ResourceId, atime_secs: i64, atime_nanos: u32, mtime_secs: i64, mtime_nanos: u32, -) -> Result<(), AnyError> -where - Fs: FileSystem + 'static, - Fs::File: Resource, -{ - let file = state.resource_table.get::<Fs::File>(rid)?; +) -> Result<(), AnyError> { + let file = FileResource::get_file(state, rid)?; file.utime_sync(atime_secs, atime_nanos, mtime_secs, mtime_nanos)?; Ok(()) } #[op] -async fn op_futime_async<Fs>( +async fn op_futime_async( state: Rc<RefCell<OpState>>, rid: ResourceId, atime_secs: i64, atime_nanos: u32, mtime_secs: i64, mtime_nanos: u32, -) -> Result<(), AnyError> -where - Fs: FileSystem + 'static, - Fs::File: Resource, -{ - let file = state.borrow().resource_table.get::<Fs::File>(rid)?; +) -> Result<(), AnyError> { + let file = FileResource::get_file(&state.borrow(), rid)?; file .utime_async(atime_secs, atime_nanos, mtime_secs, mtime_nanos) .await?; diff --git a/ext/fs/std_fs.rs b/ext/fs/std_fs.rs index 4bdbf4943..a657939db 100644 --- a/ext/fs/std_fs.rs +++ b/ext/fs/std_fs.rs @@ -4,34 +4,29 @@ use std::fs; use std::io; -use std::io::Read; -use std::io::Seek; use std::io::Write; use std::path::Path; use std::path::PathBuf; use std::rc::Rc; -use std::time::SystemTime; -use std::time::UNIX_EPOCH; -use deno_io::StdFileResource; -use fs3::FileExt; +use deno_io::fs::File; +use deno_io::fs::FsResult; +use deno_io::fs::FsStat; +use deno_io::StdFileResourceInner; use crate::interface::FsDirEntry; -use crate::interface::FsError; use crate::interface::FsFileType; -use crate::interface::FsResult; -use crate::interface::FsStat; -use crate::File; use crate::FileSystem; use crate::OpenOptions; +#[cfg(not(unix))] +use deno_io::fs::FsError; + #[derive(Clone)] -pub struct StdFs; +pub struct RealFs; #[async_trait::async_trait(?Send)] -impl FileSystem for StdFs { - type File = StdFileResource; - +impl FileSystem for RealFs { fn cwd(&self) -> FsResult<PathBuf> { std::env::current_dir().map_err(Into::into) } @@ -40,7 +35,7 @@ impl FileSystem for StdFs { Ok(std::env::temp_dir()) } - fn chdir(&self, path: impl AsRef<Path>) -> FsResult<()> { + fn chdir(&self, path: &Path) -> FsResult<()> { std::env::set_current_dir(path).map_err(Into::into) } @@ -78,27 +73,27 @@ impl FileSystem for StdFs { fn open_sync( &self, - path: impl AsRef<Path>, + path: &Path, options: OpenOptions, - ) -> FsResult<Self::File> { + ) -> FsResult<Rc<dyn File>> { let opts = open_options(options); let std_file = opts.open(path)?; - Ok(StdFileResource::fs_file(std_file)) + Ok(Rc::new(StdFileResourceInner::file(std_file))) } async fn open_async( &self, path: PathBuf, options: OpenOptions, - ) -> FsResult<Self::File> { + ) -> FsResult<Rc<dyn File>> { let opts = open_options(options); let std_file = tokio::task::spawn_blocking(move || opts.open(path)).await??; - Ok(StdFileResource::fs_file(std_file)) + Ok(Rc::new(StdFileResourceInner::file(std_file))) } fn mkdir_sync( &self, - path: impl AsRef<Path>, + path: &Path, recursive: bool, mode: u32, ) -> FsResult<()> { @@ -110,19 +105,19 @@ impl FileSystem for StdFs { recursive: bool, mode: u32, ) -> FsResult<()> { - tokio::task::spawn_blocking(move || mkdir(path, recursive, mode)).await? + tokio::task::spawn_blocking(move || mkdir(&path, recursive, mode)).await? } - fn chmod_sync(&self, path: impl AsRef<Path>, mode: u32) -> FsResult<()> { + fn chmod_sync(&self, path: &Path, mode: u32) -> FsResult<()> { chmod(path, mode) } async fn chmod_async(&self, path: PathBuf, mode: u32) -> FsResult<()> { - tokio::task::spawn_blocking(move || chmod(path, mode)).await? + tokio::task::spawn_blocking(move || chmod(&path, mode)).await? } fn chown_sync( &self, - path: impl AsRef<Path>, + path: &Path, uid: Option<u32>, gid: Option<u32>, ) -> FsResult<()> { @@ -134,68 +129,56 @@ impl FileSystem for StdFs { uid: Option<u32>, gid: Option<u32>, ) -> FsResult<()> { - tokio::task::spawn_blocking(move || chown(path, uid, gid)).await? + tokio::task::spawn_blocking(move || chown(&path, uid, gid)).await? } - fn remove_sync( - &self, - path: impl AsRef<Path>, - recursive: bool, - ) -> FsResult<()> { + fn remove_sync(&self, path: &Path, recursive: bool) -> FsResult<()> { remove(path, recursive) } async fn remove_async(&self, path: PathBuf, recursive: bool) -> FsResult<()> { - tokio::task::spawn_blocking(move || remove(path, recursive)).await? + tokio::task::spawn_blocking(move || remove(&path, recursive)).await? } - fn copy_file_sync( - &self, - from: impl AsRef<Path>, - to: impl AsRef<Path>, - ) -> FsResult<()> { + fn copy_file_sync(&self, from: &Path, to: &Path) -> FsResult<()> { copy_file(from, to) } async fn copy_file_async(&self, from: PathBuf, to: PathBuf) -> FsResult<()> { - tokio::task::spawn_blocking(move || copy_file(from, to)).await? + tokio::task::spawn_blocking(move || copy_file(&from, &to)).await? } - fn stat_sync(&self, path: impl AsRef<Path>) -> FsResult<FsStat> { + fn stat_sync(&self, path: &Path) -> FsResult<FsStat> { stat(path).map(Into::into) } async fn stat_async(&self, path: PathBuf) -> FsResult<FsStat> { - tokio::task::spawn_blocking(move || stat(path)) + tokio::task::spawn_blocking(move || stat(&path)) .await? .map(Into::into) } - fn lstat_sync(&self, path: impl AsRef<Path>) -> FsResult<FsStat> { + fn lstat_sync(&self, path: &Path) -> FsResult<FsStat> { lstat(path).map(Into::into) } async fn lstat_async(&self, path: PathBuf) -> FsResult<FsStat> { - tokio::task::spawn_blocking(move || lstat(path)) + tokio::task::spawn_blocking(move || lstat(&path)) .await? .map(Into::into) } - fn realpath_sync(&self, path: impl AsRef<Path>) -> FsResult<PathBuf> { + fn realpath_sync(&self, path: &Path) -> FsResult<PathBuf> { realpath(path) } async fn realpath_async(&self, path: PathBuf) -> FsResult<PathBuf> { - tokio::task::spawn_blocking(move || realpath(path)).await? + tokio::task::spawn_blocking(move || realpath(&path)).await? } - fn read_dir_sync(&self, path: impl AsRef<Path>) -> FsResult<Vec<FsDirEntry>> { + fn read_dir_sync(&self, path: &Path) -> FsResult<Vec<FsDirEntry>> { read_dir(path) } async fn read_dir_async(&self, path: PathBuf) -> FsResult<Vec<FsDirEntry>> { - tokio::task::spawn_blocking(move || read_dir(path)).await? + tokio::task::spawn_blocking(move || read_dir(&path)).await? } - fn rename_sync( - &self, - oldpath: impl AsRef<Path>, - newpath: impl AsRef<Path>, - ) -> FsResult<()> { + fn rename_sync(&self, oldpath: &Path, newpath: &Path) -> FsResult<()> { fs::rename(oldpath, newpath).map_err(Into::into) } async fn rename_async( @@ -208,11 +191,7 @@ impl FileSystem for StdFs { .map_err(Into::into) } - fn link_sync( - &self, - oldpath: impl AsRef<Path>, - newpath: impl AsRef<Path>, - ) -> FsResult<()> { + fn link_sync(&self, oldpath: &Path, newpath: &Path) -> FsResult<()> { fs::hard_link(oldpath, newpath).map_err(Into::into) } async fn link_async( @@ -227,8 +206,8 @@ impl FileSystem for StdFs { fn symlink_sync( &self, - oldpath: impl AsRef<Path>, - newpath: impl AsRef<Path>, + oldpath: &Path, + newpath: &Path, file_type: Option<FsFileType>, ) -> FsResult<()> { symlink(oldpath, newpath, file_type) @@ -239,11 +218,11 @@ impl FileSystem for StdFs { newpath: PathBuf, file_type: Option<FsFileType>, ) -> FsResult<()> { - tokio::task::spawn_blocking(move || symlink(oldpath, newpath, file_type)) + tokio::task::spawn_blocking(move || symlink(&oldpath, &newpath, file_type)) .await? } - fn read_link_sync(&self, path: impl AsRef<Path>) -> FsResult<PathBuf> { + fn read_link_sync(&self, path: &Path) -> FsResult<PathBuf> { fs::read_link(path).map_err(Into::into) } async fn read_link_async(&self, path: PathBuf) -> FsResult<PathBuf> { @@ -252,16 +231,16 @@ impl FileSystem for StdFs { .map_err(Into::into) } - fn truncate_sync(&self, path: impl AsRef<Path>, len: u64) -> FsResult<()> { + fn truncate_sync(&self, path: &Path, len: u64) -> FsResult<()> { truncate(path, len) } async fn truncate_async(&self, path: PathBuf, len: u64) -> FsResult<()> { - tokio::task::spawn_blocking(move || truncate(path, len)).await? + tokio::task::spawn_blocking(move || truncate(&path, len)).await? } fn utime_sync( &self, - path: impl AsRef<Path>, + path: &Path, atime_secs: i64, atime_nanos: u32, mtime_secs: i64, @@ -289,7 +268,7 @@ impl FileSystem for StdFs { fn write_file_sync( &self, - path: impl AsRef<Path>, + path: &Path, options: OpenOptions, data: &[u8], ) -> FsResult<()> { @@ -324,7 +303,7 @@ impl FileSystem for StdFs { .await? } - fn read_file_sync(&self, path: impl AsRef<Path>) -> FsResult<Vec<u8>> { + fn read_file_sync(&self, path: &Path) -> FsResult<Vec<u8>> { fs::read(path).map_err(Into::into) } async fn read_file_async(&self, path: PathBuf) -> FsResult<Vec<u8>> { @@ -334,7 +313,7 @@ impl FileSystem for StdFs { } } -fn mkdir(path: impl AsRef<Path>, recursive: bool, mode: u32) -> FsResult<()> { +fn mkdir(path: &Path, recursive: bool, mode: u32) -> FsResult<()> { let mut builder = fs::DirBuilder::new(); builder.recursive(recursive); #[cfg(unix)] @@ -350,7 +329,7 @@ fn mkdir(path: impl AsRef<Path>, recursive: bool, mode: u32) -> FsResult<()> { } #[cfg(unix)] -fn chmod(path: impl AsRef<Path>, mode: u32) -> FsResult<()> { +fn chmod(path: &Path, mode: u32) -> FsResult<()> { use std::os::unix::fs::PermissionsExt; let permissions = fs::Permissions::from_mode(mode); fs::set_permissions(path, permissions)?; @@ -359,24 +338,20 @@ fn chmod(path: impl AsRef<Path>, mode: u32) -> FsResult<()> { // TODO: implement chmod for Windows (#4357) #[cfg(not(unix))] -fn chmod(path: impl AsRef<Path>, _mode: u32) -> FsResult<()> { +fn chmod(path: &Path, _mode: u32) -> FsResult<()> { // Still check file/dir exists on Windows std::fs::metadata(path)?; Err(FsError::NotSupported) } #[cfg(unix)] -fn chown( - path: impl AsRef<Path>, - uid: Option<u32>, - gid: Option<u32>, -) -> FsResult<()> { +fn chown(path: &Path, uid: Option<u32>, gid: Option<u32>) -> FsResult<()> { use nix::unistd::chown; use nix::unistd::Gid; use nix::unistd::Uid; let owner = uid.map(Uid::from_raw); let group = gid.map(Gid::from_raw); - let res = chown(path.as_ref(), owner, group); + let res = chown(path, owner, group); if let Err(err) = res { return Err(io::Error::from_raw_os_error(err as i32).into()); } @@ -385,60 +360,57 @@ fn chown( // TODO: implement chown for Windows #[cfg(not(unix))] -fn chown( - _path: impl AsRef<Path>, - _uid: Option<u32>, - _gid: Option<u32>, -) -> FsResult<()> { +fn chown(_path: &Path, _uid: Option<u32>, _gid: Option<u32>) -> FsResult<()> { Err(FsError::NotSupported) } -fn remove(path: impl AsRef<Path>, recursive: bool) -> FsResult<()> { +fn remove(path: &Path, recursive: bool) -> FsResult<()> { // TODO: this is racy. This should open fds, and then `unlink` those. - let metadata = fs::symlink_metadata(&path)?; + let metadata = fs::symlink_metadata(path)?; let file_type = metadata.file_type(); let res = if file_type.is_dir() { if recursive { - fs::remove_dir_all(&path) + fs::remove_dir_all(path) } else { - fs::remove_dir(&path) + fs::remove_dir(path) } } else if file_type.is_symlink() { #[cfg(unix)] { - fs::remove_file(&path) + fs::remove_file(path) } #[cfg(not(unix))] { use std::os::windows::prelude::MetadataExt; use winapi::um::winnt::FILE_ATTRIBUTE_DIRECTORY; if metadata.file_attributes() & FILE_ATTRIBUTE_DIRECTORY != 0 { - fs::remove_dir(&path) + fs::remove_dir(path) } else { - fs::remove_file(&path) + fs::remove_file(path) } } } else { - fs::remove_file(&path) + fs::remove_file(path) }; res.map_err(Into::into) } -fn copy_file(from: impl AsRef<Path>, to: impl AsRef<Path>) -> FsResult<()> { +fn copy_file(from: &Path, to: &Path) -> FsResult<()> { #[cfg(target_os = "macos")] { use libc::clonefile; use libc::stat; use libc::unlink; use std::ffi::CString; + use std::io::Read; use std::os::unix::fs::OpenOptionsExt; use std::os::unix::fs::PermissionsExt; use std::os::unix::prelude::OsStrExt; - let from_str = CString::new(from.as_ref().as_os_str().as_bytes()).unwrap(); - let to_str = CString::new(to.as_ref().as_os_str().as_bytes()).unwrap(); + let from_str = CString::new(from.as_os_str().as_bytes()).unwrap(); + let to_str = CString::new(to.as_os_str().as_bytes()).unwrap(); // SAFETY: `from` and `to` are valid C strings. // std::fs::copy does open() + fcopyfile() on macOS. We try to use @@ -499,36 +471,37 @@ fn copy_file(from: impl AsRef<Path>, to: impl AsRef<Path>) -> FsResult<()> { } #[cfg(not(windows))] -fn stat(path: impl AsRef<Path>) -> FsResult<FsStat> { +fn stat(path: &Path) -> FsResult<FsStat> { let metadata = fs::metadata(path)?; - Ok(metadata_to_fsstat(metadata)) + Ok(FsStat::from_std(metadata)) } #[cfg(windows)] -fn stat(path: impl AsRef<Path>) -> FsResult<FsStat> { - let metadata = fs::metadata(path.as_ref())?; - let mut fsstat = metadata_to_fsstat(metadata); +fn stat(path: &Path) -> FsResult<FsStat> { + let metadata = fs::metadata(path)?; + let mut fsstat = FsStat::from_std(metadata); use winapi::um::winbase::FILE_FLAG_BACKUP_SEMANTICS; - let path = path.as_ref().canonicalize()?; + let path = path.canonicalize()?; stat_extra(&mut fsstat, &path, FILE_FLAG_BACKUP_SEMANTICS)?; Ok(fsstat) } #[cfg(not(windows))] -fn lstat(path: impl AsRef<Path>) -> FsResult<FsStat> { +fn lstat(path: &Path) -> FsResult<FsStat> { let metadata = fs::symlink_metadata(path)?; - Ok(metadata_to_fsstat(metadata)) + Ok(FsStat::from_std(metadata)) } #[cfg(windows)] -fn lstat(path: impl AsRef<Path>) -> FsResult<FsStat> { - let metadata = fs::symlink_metadata(path.as_ref())?; - let mut fsstat = metadata_to_fsstat(metadata); +fn lstat(path: &Path) -> FsResult<FsStat> { use winapi::um::winbase::FILE_FLAG_BACKUP_SEMANTICS; use winapi::um::winbase::FILE_FLAG_OPEN_REPARSE_POINT; + + let metadata = fs::symlink_metadata(path)?; + let mut fsstat = FsStat::from_std(metadata); stat_extra( &mut fsstat, - path.as_ref(), + path, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, )?; Ok(fsstat) @@ -595,62 +568,11 @@ fn stat_extra( } } -#[inline(always)] -fn metadata_to_fsstat(metadata: fs::Metadata) -> FsStat { - macro_rules! unix_or_zero { - ($member:ident) => {{ - #[cfg(unix)] - { - use std::os::unix::fs::MetadataExt; - metadata.$member() - } - #[cfg(not(unix))] - { - 0 - } - }}; - } - - #[inline(always)] - fn to_msec(maybe_time: Result<SystemTime, io::Error>) -> Option<u64> { - match maybe_time { - Ok(time) => Some( - time - .duration_since(UNIX_EPOCH) - .map(|t| t.as_millis() as u64) - .unwrap_or_else(|err| err.duration().as_millis() as u64), - ), - Err(_) => None, - } - } - - FsStat { - is_file: metadata.is_file(), - is_directory: metadata.is_dir(), - is_symlink: metadata.file_type().is_symlink(), - size: metadata.len(), - - mtime: to_msec(metadata.modified()), - atime: to_msec(metadata.accessed()), - birthtime: to_msec(metadata.created()), - - dev: unix_or_zero!(dev), - ino: unix_or_zero!(ino), - mode: unix_or_zero!(mode), - nlink: unix_or_zero!(nlink), - uid: unix_or_zero!(uid), - gid: unix_or_zero!(gid), - rdev: unix_or_zero!(rdev), - blksize: unix_or_zero!(blksize), - blocks: unix_or_zero!(blocks), - } -} - -fn realpath(path: impl AsRef<Path>) -> FsResult<PathBuf> { - Ok(deno_core::strip_unc_prefix(path.as_ref().canonicalize()?)) +fn realpath(path: &Path) -> FsResult<PathBuf> { + Ok(deno_core::strip_unc_prefix(path.canonicalize()?)) } -fn read_dir(path: impl AsRef<Path>) -> FsResult<Vec<FsDirEntry>> { +fn read_dir(path: &Path) -> FsResult<Vec<FsDirEntry>> { let entries = fs::read_dir(path)? .filter_map(|entry| { let entry = entry.ok()?; @@ -679,24 +601,24 @@ fn read_dir(path: impl AsRef<Path>) -> FsResult<Vec<FsDirEntry>> { #[cfg(not(windows))] fn symlink( - oldpath: impl AsRef<Path>, - newpath: impl AsRef<Path>, + oldpath: &Path, + newpath: &Path, _file_type: Option<FsFileType>, ) -> FsResult<()> { - std::os::unix::fs::symlink(oldpath.as_ref(), newpath.as_ref())?; + std::os::unix::fs::symlink(oldpath, newpath)?; Ok(()) } #[cfg(windows)] fn symlink( - oldpath: impl AsRef<Path>, - newpath: impl AsRef<Path>, + oldpath: &Path, + newpath: &Path, file_type: Option<FsFileType>, ) -> FsResult<()> { let file_type = match file_type { Some(file_type) => file_type, None => { - let old_meta = fs::metadata(&oldpath); + let old_meta = fs::metadata(oldpath); match old_meta { Ok(metadata) => { if metadata.is_file() { @@ -723,17 +645,17 @@ fn symlink( match file_type { FsFileType::File => { - std::os::windows::fs::symlink_file(&oldpath, &newpath)?; + std::os::windows::fs::symlink_file(oldpath, newpath)?; } FsFileType::Directory => { - std::os::windows::fs::symlink_dir(&oldpath, &newpath)?; + std::os::windows::fs::symlink_dir(oldpath, newpath)?; } }; Ok(()) } -fn truncate(path: impl AsRef<Path>, len: u64) -> FsResult<()> { +fn truncate(path: &Path, len: u64) -> FsResult<()> { let file = fs::OpenOptions::new().write(true).open(path)?; file.set_len(len)?; Ok(()) @@ -760,162 +682,3 @@ fn open_options(options: OpenOptions) -> fs::OpenOptions { open_options.create_new(options.create_new); open_options } - -fn sync<T>( - resource: Rc<StdFileResource>, - f: impl FnOnce(&mut fs::File) -> io::Result<T>, -) -> FsResult<T> { - let res = resource - .with_file2(|file| f(file)) - .ok_or(FsError::FileBusy)??; - Ok(res) -} - -async fn nonblocking<T: Send + 'static>( - resource: Rc<StdFileResource>, - f: impl FnOnce(&mut fs::File) -> io::Result<T> + Send + 'static, -) -> FsResult<T> { - let res = resource.with_file_blocking_task2(f).await?; - Ok(res) -} - -#[async_trait::async_trait(?Send)] -impl File for StdFileResource { - fn write_all_sync(self: Rc<Self>, buf: &[u8]) -> FsResult<()> { - sync(self, |file| file.write_all(buf)) - } - async fn write_all_async(self: Rc<Self>, buf: Vec<u8>) -> FsResult<()> { - nonblocking(self, move |file| file.write_all(&buf)).await - } - - fn read_all_sync(self: Rc<Self>) -> FsResult<Vec<u8>> { - sync(self, |file| { - let mut buf = Vec::new(); - file.read_to_end(&mut buf)?; - Ok(buf) - }) - } - async fn read_all_async(self: Rc<Self>) -> FsResult<Vec<u8>> { - nonblocking(self, |file| { - let mut buf = Vec::new(); - file.read_to_end(&mut buf)?; - Ok(buf) - }) - .await - } - - fn chmod_sync(self: Rc<Self>, _mode: u32) -> FsResult<()> { - #[cfg(unix)] - { - sync(self, |file| { - use std::os::unix::prelude::PermissionsExt; - file.set_permissions(fs::Permissions::from_mode(_mode)) - }) - } - #[cfg(not(unix))] - Err(FsError::NotSupported) - } - - async fn chmod_async(self: Rc<Self>, _mode: u32) -> FsResult<()> { - #[cfg(unix)] - { - nonblocking(self, move |file| { - use std::os::unix::prelude::PermissionsExt; - file.set_permissions(fs::Permissions::from_mode(_mode)) - }) - .await - } - #[cfg(not(unix))] - Err(FsError::NotSupported) - } - - fn seek_sync(self: Rc<Self>, pos: io::SeekFrom) -> FsResult<u64> { - sync(self, |file| file.seek(pos)) - } - async fn seek_async(self: Rc<Self>, pos: io::SeekFrom) -> FsResult<u64> { - nonblocking(self, move |file| file.seek(pos)).await - } - - fn datasync_sync(self: Rc<Self>) -> FsResult<()> { - sync(self, |file| file.sync_data()) - } - async fn datasync_async(self: Rc<Self>) -> FsResult<()> { - nonblocking(self, |file| file.sync_data()).await - } - - fn sync_sync(self: Rc<Self>) -> FsResult<()> { - sync(self, |file| file.sync_all()) - } - async fn sync_async(self: Rc<Self>) -> FsResult<()> { - nonblocking(self, |file| file.sync_all()).await - } - - fn stat_sync(self: Rc<Self>) -> FsResult<FsStat> { - sync(self, |file| file.metadata().map(metadata_to_fsstat)) - } - async fn stat_async(self: Rc<Self>) -> FsResult<FsStat> { - nonblocking(self, |file| file.metadata().map(metadata_to_fsstat)).await - } - - fn lock_sync(self: Rc<Self>, exclusive: bool) -> FsResult<()> { - sync(self, |file| { - if exclusive { - file.lock_exclusive() - } else { - file.lock_shared() - } - }) - } - async fn lock_async(self: Rc<Self>, exclusive: bool) -> FsResult<()> { - nonblocking(self, move |file| { - if exclusive { - file.lock_exclusive() - } else { - file.lock_shared() - } - }) - .await - } - - fn unlock_sync(self: Rc<Self>) -> FsResult<()> { - sync(self, |file| file.unlock()) - } - async fn unlock_async(self: Rc<Self>) -> FsResult<()> { - nonblocking(self, |file| file.unlock()).await - } - - fn truncate_sync(self: Rc<Self>, len: u64) -> FsResult<()> { - sync(self, |file| file.set_len(len)) - } - async fn truncate_async(self: Rc<Self>, len: u64) -> FsResult<()> { - nonblocking(self, move |file| file.set_len(len)).await - } - - fn utime_sync( - self: Rc<Self>, - atime_secs: i64, - atime_nanos: u32, - mtime_secs: i64, - mtime_nanos: u32, - ) -> FsResult<()> { - let atime = filetime::FileTime::from_unix_time(atime_secs, atime_nanos); - let mtime = filetime::FileTime::from_unix_time(mtime_secs, mtime_nanos); - sync(self, |file| { - filetime::set_file_handle_times(file, Some(atime), Some(mtime)) - }) - } - async fn utime_async( - self: Rc<Self>, - atime_secs: i64, - atime_nanos: u32, - mtime_secs: i64, - mtime_nanos: u32, - ) -> FsResult<()> { - let atime = filetime::FileTime::from_unix_time(atime_secs, atime_nanos); - let mtime = filetime::FileTime::from_unix_time(mtime_secs, mtime_nanos); - nonblocking(self, move |file| { - filetime::set_file_handle_times(file, Some(atime), Some(mtime)) - }) - .await - } -} |
