summaryrefslogtreecommitdiff
path: root/ext/fs
diff options
context:
space:
mode:
authorLuca Casonato <hello@lcas.dev>2023-04-17 16:10:59 +0200
committerGitHub <noreply@github.com>2023-04-17 16:10:59 +0200
commitbcbdaac7e6399870b5b6fcdf765013c1682fe80c (patch)
tree990e98d3787775a6349e444dc68eac352d69bd66 /ext/fs
parentbad4b7554bd499975170f7d4e1a30540783aea69 (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.rs63
-rw-r--r--ext/fs/lib.rs39
-rw-r--r--ext/fs/ops.rs52
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