diff options
author | Luca Casonato <hello@lcas.dev> | 2023-04-17 16:10:59 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-04-17 16:10:59 +0200 |
commit | bcbdaac7e6399870b5b6fcdf765013c1682fe80c (patch) | |
tree | 990e98d3787775a6349e444dc68eac352d69bd66 /ext/fs | |
parent | bad4b7554bd499975170f7d4e1a30540783aea69 (diff) |
chore(ext/fs): decouple fs trait from deno_core (#18732)
This commit removes the dependencies on `deno_core` for the Fs trait.
This allows to move the trait into a different crate that does not
depend on core in the limit.
This adds a new `bounds` field to `deno_core::extension!` that expands
to `where` clauses on the generated code. This allows to add bounds to
the extension parameters, such as `Fs::File: Resource`.
Diffstat (limited to 'ext/fs')
-rw-r--r-- | ext/fs/interface.rs | 63 | ||||
-rw-r--r-- | ext/fs/lib.rs | 39 | ||||
-rw-r--r-- | ext/fs/ops.rs | 52 |
3 files changed, 87 insertions, 67 deletions
diff --git a/ext/fs/interface.rs b/ext/fs/interface.rs index a68260051..184cb8096 100644 --- a/ext/fs/interface.rs +++ b/ext/fs/interface.rs @@ -5,32 +5,8 @@ use std::path::Path; use std::path::PathBuf; use std::rc::Rc; -use deno_core::error::not_supported; -use deno_core::error::resource_unavailable; -use deno_core::error::AnyError; -use deno_core::Resource; use serde::Deserialize; use serde::Serialize; -use tokio::task::JoinError; - -pub trait FsPermissions { - fn check_read(&mut self, p: &Path, api_name: &str) -> Result<(), AnyError>; - fn check_read_all(&mut self, api_name: &str) -> Result<(), AnyError>; - fn check_read_blind( - &mut self, - p: &Path, - display: &str, - api_name: &str, - ) -> Result<(), AnyError>; - fn check_write(&mut self, p: &Path, api_name: &str) -> Result<(), AnyError>; - fn check_write_all(&mut self, api_name: &str) -> Result<(), AnyError>; - fn check_write_blind( - &mut self, - p: &Path, - display: &str, - api_name: &str, - ) -> Result<(), AnyError>; -} #[derive(Deserialize, Default, Debug, Clone, Copy)] #[serde(rename_all = "camelCase")] @@ -74,21 +50,6 @@ impl OpenOptions { mode, } } - - pub(crate) fn check<P: FsPermissions>( - &self, - permissions: &mut P, - path: &Path, - api_name: &str, - ) -> Result<(), AnyError> { - if self.read { - permissions.check_read(path, api_name)?; - } - if self.write || self.append { - permissions.check_write(path, api_name)?; - } - Ok(()) - } } pub struct FsStat { @@ -141,28 +102,6 @@ impl From<io::Error> for FsError { } } -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(), - } - } -} - pub type FsResult<T> = Result<T, FsError>; #[async_trait::async_trait(?Send)] @@ -214,7 +153,7 @@ pub trait File { #[async_trait::async_trait(?Send)] pub trait FileSystem: Clone { - type File: File + Resource; + type File: File; fn cwd(&self) -> FsResult<PathBuf>; fn tmp_dir(&self) -> FsResult<PathBuf>; diff --git a/ext/fs/lib.rs b/ext/fs/lib.rs index c1418815c..464d84ade 100644 --- a/ext/fs/lib.rs +++ b/ext/fs/lib.rs @@ -9,7 +9,6 @@ pub use crate::interface::FileSystem; pub use crate::interface::FsDirEntry; pub use crate::interface::FsError; pub use crate::interface::FsFileType; -pub use crate::interface::FsPermissions; pub use crate::interface::FsResult; pub use crate::interface::FsStat; pub use crate::interface::OpenOptions; @@ -17,11 +16,48 @@ use crate::ops::*; pub use crate::std_fs::StdFs; +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; +pub trait FsPermissions { + fn check_read(&mut self, p: &Path, api_name: &str) -> Result<(), AnyError>; + fn check_read_all(&mut self, api_name: &str) -> Result<(), AnyError>; + fn check_read_blind( + &mut self, + p: &Path, + display: &str, + api_name: &str, + ) -> Result<(), AnyError>; + fn check_write(&mut self, p: &Path, api_name: &str) -> Result<(), AnyError>; + fn check_write_all(&mut self, api_name: &str) -> Result<(), AnyError>; + fn check_write_blind( + &mut self, + p: &Path, + display: &str, + api_name: &str, + ) -> Result<(), AnyError>; + + fn check( + &mut self, + open_options: &OpenOptions, + path: &Path, + api_name: &str, + ) -> Result<(), AnyError> { + if open_options.read { + self.check_read(path, api_name)?; + } + if open_options.write || open_options.append { + self.check_write(path, api_name)?; + } + Ok(()) + } +} + struct UnstableChecker { pub unstable: bool, } @@ -52,6 +88,7 @@ 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], ops = [ op_cwd<Fs, P>, op_umask<Fs>, diff --git a/ext/fs/ops.rs b/ext/fs/ops.rs index c1381d89c..8c5d21201 100644 --- a/ext/fs/ops.rs +++ b/ext/fs/ops.rs @@ -9,18 +9,22 @@ use std::path::PathBuf; use std::rc::Rc; 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 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; @@ -33,6 +37,28 @@ 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> where @@ -76,13 +102,14 @@ fn op_open_sync<Fs, P>( ) -> Result<ResourceId, AnyError> where Fs: FileSystem + 'static, + Fs::File: Resource, P: FsPermissions + 'static, { let path = PathBuf::from(path); let options = options.unwrap_or_else(OpenOptions::read); let permissions = state.borrow_mut::<P>(); - options.check(permissions, &path, "Deno.openSync()")?; + permissions.check(&options, &path, "Deno.openSync()")?; let fs = state.borrow::<Fs>(); let file = fs.open_sync(&path, options).context_path("open", &path)?; @@ -99,6 +126,7 @@ async fn op_open_async<Fs, P>( ) -> Result<ResourceId, AnyError> where Fs: FileSystem + 'static, + Fs::File: Resource, P: FsPermissions + 'static, { let path = PathBuf::from(path); @@ -107,7 +135,7 @@ where let fs = { let mut state = state.borrow_mut(); let permissions = state.borrow_mut::<P>(); - options.check(permissions, &path, "Deno.open()")?; + permissions.check(&options, &path, "Deno.open()")?; state.borrow::<Fs>().clone() }; let file = fs @@ -1117,7 +1145,7 @@ where let permissions = state.borrow_mut::<P>(); let options = OpenOptions::write(create, append, create_new, mode); - options.check(permissions, &path, "Deno.writeFileSync()")?; + permissions.check(&options, &path, "Deno.writeFileSync()")?; let fs = state.borrow::<Fs>(); @@ -1149,7 +1177,7 @@ where let (fs, cancel_handle) = { let mut state = state.borrow_mut(); let permissions = state.borrow_mut::<P>(); - options.check(permissions, &path, "Deno.writeFile()")?; + 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) @@ -1320,6 +1348,7 @@ fn op_seek_sync<Fs>( ) -> Result<u64, AnyError> where Fs: FileSystem + 'static, + Fs::File: Resource, { let pos = to_seek_from(offset, whence)?; let file = state.resource_table.get::<Fs::File>(rid)?; @@ -1336,6 +1365,7 @@ async fn op_seek_async<Fs>( ) -> Result<u64, AnyError> where Fs: FileSystem + 'static, + Fs::File: Resource, { let pos = to_seek_from(offset, whence)?; let file = state.borrow().resource_table.get::<Fs::File>(rid)?; @@ -1350,6 +1380,7 @@ fn op_fdatasync_sync<Fs>( ) -> Result<(), AnyError> where Fs: FileSystem + 'static, + Fs::File: Resource, { let file = state.resource_table.get::<Fs::File>(rid)?; file.datasync_sync()?; @@ -1363,6 +1394,7 @@ async fn op_fdatasync_async<Fs>( ) -> Result<(), AnyError> where Fs: FileSystem + 'static, + Fs::File: Resource, { let file = state.borrow().resource_table.get::<Fs::File>(rid)?; file.datasync_async().await?; @@ -1376,6 +1408,7 @@ fn op_fsync_sync<Fs>( ) -> Result<(), AnyError> where Fs: FileSystem + 'static, + Fs::File: Resource, { let file = state.resource_table.get::<Fs::File>(rid)?; file.sync_sync()?; @@ -1389,6 +1422,7 @@ async fn op_fsync_async<Fs>( ) -> Result<(), AnyError> where Fs: FileSystem + 'static, + Fs::File: Resource, { let file = state.borrow().resource_table.get::<Fs::File>(rid)?; file.sync_async().await?; @@ -1403,6 +1437,7 @@ fn op_fstat_sync<Fs>( ) -> Result<(), AnyError> where Fs: FileSystem + 'static, + Fs::File: Resource, { let file = state.resource_table.get::<Fs::File>(rid)?; let stat = file.stat_sync()?; @@ -1418,6 +1453,7 @@ async fn op_fstat_async<Fs>( ) -> Result<SerializableStat, AnyError> where Fs: FileSystem + 'static, + Fs::File: Resource, { let file = state.borrow().resource_table.get::<Fs::File>(rid)?; let stat = file.stat_async().await?; @@ -1432,6 +1468,7 @@ fn op_flock_sync<Fs>( ) -> Result<(), AnyError> where Fs: FileSystem + 'static, + Fs::File: Resource, { check_unstable(state, "Deno.flockSync"); let file = state.resource_table.get::<Fs::File>(rid)?; @@ -1447,6 +1484,7 @@ async fn op_flock_async<Fs>( ) -> Result<(), AnyError> where Fs: FileSystem + 'static, + Fs::File: Resource, { check_unstable2(&state, "Deno.flock"); let file = state.borrow().resource_table.get::<Fs::File>(rid)?; @@ -1461,6 +1499,7 @@ fn op_funlock_sync<Fs>( ) -> Result<(), AnyError> where Fs: FileSystem + 'static, + Fs::File: Resource, { check_unstable(state, "Deno.funlockSync"); let file = state.resource_table.get::<Fs::File>(rid)?; @@ -1475,6 +1514,7 @@ async fn op_funlock_async<Fs>( ) -> Result<(), AnyError> where Fs: FileSystem + 'static, + Fs::File: Resource, { check_unstable2(&state, "Deno.funlock"); let file = state.borrow().resource_table.get::<Fs::File>(rid)?; @@ -1490,6 +1530,7 @@ fn op_ftruncate_sync<Fs>( ) -> Result<(), AnyError> where Fs: FileSystem + 'static, + Fs::File: Resource, { let file = state.resource_table.get::<Fs::File>(rid)?; file.truncate_sync(len)?; @@ -1504,6 +1545,7 @@ async fn op_ftruncate_async<Fs>( ) -> Result<(), AnyError> where Fs: FileSystem + 'static, + Fs::File: Resource, { let file = state.borrow().resource_table.get::<Fs::File>(rid)?; file.truncate_async(len).await?; @@ -1521,6 +1563,7 @@ fn op_futime_sync<Fs>( ) -> Result<(), AnyError> where Fs: FileSystem + 'static, + Fs::File: Resource, { let file = state.resource_table.get::<Fs::File>(rid)?; file.utime_sync(atime_secs, atime_nanos, mtime_secs, mtime_nanos)?; @@ -1538,6 +1581,7 @@ async fn op_futime_async<Fs>( ) -> Result<(), AnyError> where Fs: FileSystem + 'static, + Fs::File: Resource, { let file = state.borrow().resource_table.get::<Fs::File>(rid)?; file |