Skip to content

Commit

Permalink
port cli/ops/fs.rs to json ops, part 2
Browse files Browse the repository at this point in the history
  • Loading branch information
bartlomieju committed Aug 24, 2019
1 parent f3c7834 commit d32dfd6
Show file tree
Hide file tree
Showing 10 changed files with 180 additions and 219 deletions.
41 changes: 0 additions & 41 deletions cli/msg.fbs
Original file line number Diff line number Diff line change
@@ -1,21 +1,15 @@
union Any {
CopyFile,
Cwd,
CwdRes,
Link,
MakeTempDir,
MakeTempDirRes,
Read,
ReadDir,
ReadDirRes,
ReadRes,
Readlink,
ReadlinkRes,
Remove,
Rename,
Seek,
Stat,
StatRes,
Symlink,
Truncate,
Write,
Expand Down Expand Up @@ -133,24 +127,6 @@ table MakeTempDirRes {
path: string;
}

table Remove {
path: string;
recursive: bool;
}

table ReadDir {
path: string;
}

table ReadDirRes {
entries: [StatRes];
}

table CopyFile {
from: string;
to: string;
}

table Rename {
oldpath: string;
newpath: string;
Expand All @@ -174,23 +150,6 @@ table Link {
newname: string;
}

table Stat {
filename: string;
lstat: bool;
}

table StatRes {
is_file: bool;
is_symlink: bool;
len: ulong;
modified:ulong;
accessed:ulong;
created:ulong;
mode: uint;
has_mode: bool; // false on windows
name: string;
}

table Truncate {
name: string;
len: uint;
Expand Down
8 changes: 2 additions & 6 deletions cli/ops/dispatch_flatbuffers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ use hyper::rt::Future;

use super::files::{op_read, op_write};
use super::fs::{
op_copy_file, op_cwd, op_link, op_make_temp_dir, op_read_dir, op_read_link,
op_remove, op_rename, op_stat, op_symlink, op_truncate,
op_cwd, op_link, op_make_temp_dir, op_read_link, op_rename, op_symlink,
op_truncate,
};

type CliDispatchFn = fn(
Expand Down Expand Up @@ -124,16 +124,12 @@ pub fn serialize_response(
/// Standard ops set for most isolates
pub fn op_selector_std(inner_type: msg::Any) -> Option<CliDispatchFn> {
match inner_type {
msg::Any::CopyFile => Some(op_copy_file),
msg::Any::Cwd => Some(op_cwd),
msg::Any::Link => Some(op_link),
msg::Any::MakeTempDir => Some(op_make_temp_dir),
msg::Any::Read => Some(op_read),
msg::Any::ReadDir => Some(op_read_dir),
msg::Any::Readlink => Some(op_read_link),
msg::Any::Remove => Some(op_remove),
msg::Any::Rename => Some(op_rename),
msg::Any::Stat => Some(op_stat),
msg::Any::Symlink => Some(op_symlink),
msg::Any::Truncate => Some(op_truncate),
msg::Any::Write => Some(op_write),
Expand Down
183 changes: 90 additions & 93 deletions cli/ops/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,19 +121,27 @@ pub fn op_chown(
})
}

#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
struct RemoveArgs {
promise_id: Option<u64>,
path: String,
recursive: bool,
}

pub fn op_remove(
state: &ThreadSafeState,
base: &msg::Base<'_>,
data: Option<PinnedBuf>,
) -> CliOpResult {
assert!(data.is_none());
let inner = base.inner_as_remove().unwrap();
let (path, path_) = deno_fs::resolve_from_cwd(inner.path().unwrap())?;
let recursive = inner.recursive();
args: Value,
_zero_copy: Option<PinnedBuf>,
) -> Result<JsonOp, ErrBox> {
let args: RemoveArgs = serde_json::from_value(args)?;
let (path, path_) = deno_fs::resolve_from_cwd(args.path.as_ref())?;
let recursive = args.recursive;

state.check_write(&path_)?;

blocking(base.sync(), move || {
let is_sync = args.promise_id.is_none();
blocking_json(is_sync, move || {
debug!("op_remove {}", path.display());
let metadata = fs::metadata(&path)?;
if metadata.is_file() {
Expand All @@ -143,25 +151,34 @@ pub fn op_remove(
} else {
fs::remove_dir(&path)?;
}
Ok(empty_buf())
Ok(json!({}))
})
}

#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
struct CopyFileArgs {
promise_id: Option<u64>,
from: String,
to: String,
}

pub fn op_copy_file(
state: &ThreadSafeState,
base: &msg::Base<'_>,
data: Option<PinnedBuf>,
) -> CliOpResult {
assert!(data.is_none());
let inner = base.inner_as_copy_file().unwrap();
let (from, from_) = deno_fs::resolve_from_cwd(inner.from().unwrap())?;
let (to, to_) = deno_fs::resolve_from_cwd(inner.to().unwrap())?;
args: Value,
_zero_copy: Option<PinnedBuf>,
) -> Result<JsonOp, ErrBox> {
let args: CopyFileArgs = serde_json::from_value(args)?;

let (from, from_) = deno_fs::resolve_from_cwd(args.from.as_ref())?;
let (to, to_) = deno_fs::resolve_from_cwd(args.to.as_ref())?;

state.check_read(&from_)?;
state.check_write(&to_)?;

debug!("op_copy_file {} {}", from.display(), to.display());
blocking(base.sync(), move || {
let is_sync = args.promise_id.is_none();
blocking_json(is_sync, move || {
// On *nix, Rust deem non-existent path as invalid input
// See https://github.com/rust-lang/rust/issues/54800
// Once the issue is reolved, we should remove this workaround.
Expand All @@ -173,7 +190,7 @@ pub fn op_copy_file(
}

fs::copy(&from, &to)?;
Ok(empty_buf())
Ok(json!({}))
})
}

Expand All @@ -197,111 +214,91 @@ fn get_mode(_perm: &fs::Permissions) -> u32 {
0
}

#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
struct StatArgs {
promise_id: Option<u64>,
filename: String,
lstat: bool,
}

pub fn op_stat(
state: &ThreadSafeState,
base: &msg::Base<'_>,
data: Option<PinnedBuf>,
) -> CliOpResult {
assert!(data.is_none());
let inner = base.inner_as_stat().unwrap();
let cmd_id = base.cmd_id();
args: Value,
_zero_copy: Option<PinnedBuf>,
) -> Result<JsonOp, ErrBox> {
let args: StatArgs = serde_json::from_value(args)?;

let (filename, filename_) =
deno_fs::resolve_from_cwd(inner.filename().unwrap())?;
let lstat = inner.lstat();
deno_fs::resolve_from_cwd(args.filename.as_ref())?;
let lstat = args.lstat;

state.check_read(&filename_)?;

blocking(base.sync(), move || {
let builder = &mut FlatBufferBuilder::new();
let is_sync = args.promise_id.is_none();
blocking_json(is_sync, move || {
debug!("op_stat {} {}", filename.display(), lstat);
let metadata = if lstat {
fs::symlink_metadata(&filename)?
} else {
fs::metadata(&filename)?
};

let inner = msg::StatRes::create(
builder,
&msg::StatResArgs {
is_file: metadata.is_file(),
is_symlink: metadata.file_type().is_symlink(),
len: metadata.len(),
modified: to_seconds!(metadata.modified()),
accessed: to_seconds!(metadata.accessed()),
created: to_seconds!(metadata.created()),
mode: get_mode(&metadata.permissions()),
has_mode: cfg!(target_family = "unix"),
..Default::default()
},
);

Ok(serialize_response(
cmd_id,
builder,
msg::BaseArgs {
inner: Some(inner.as_union_value()),
inner_type: msg::Any::StatRes,
..Default::default()
},
))
Ok(json!({
"isFile": metadata.is_file(),
"isSymlink": metadata.file_type().is_symlink(),
"len": metadata.len(),
"modified":to_seconds!(metadata.modified()),
"accessed":to_seconds!(metadata.accessed()),
"created":to_seconds!(metadata.created()),
"mode": get_mode(&metadata.permissions()),
"hasMode": cfg!(target_family = "unix"), // false on windows,
}))
})
}

#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
struct ReadDirArgs {
promise_id: Option<u64>,
path: String,
}

pub fn op_read_dir(
state: &ThreadSafeState,
base: &msg::Base<'_>,
data: Option<PinnedBuf>,
) -> CliOpResult {
assert!(data.is_none());
let inner = base.inner_as_read_dir().unwrap();
let cmd_id = base.cmd_id();
let (path, path_) = deno_fs::resolve_from_cwd(inner.path().unwrap())?;
args: Value,
_zero_copy: Option<PinnedBuf>,
) -> Result<JsonOp, ErrBox> {
let args: ReadDirArgs = serde_json::from_value(args)?;
let (path, path_) = deno_fs::resolve_from_cwd(args.path.as_ref())?;

state.check_read(&path_)?;

blocking(base.sync(), move || {
let is_sync = args.promise_id.is_none();
blocking_json(is_sync, move || {
debug!("op_read_dir {}", path.display());
let builder = &mut FlatBufferBuilder::new();

let entries: Vec<_> = fs::read_dir(path)?
.map(|entry| {
let entry = entry.unwrap();
let metadata = entry.metadata().unwrap();
let file_type = metadata.file_type();
let name = builder.create_string(entry.file_name().to_str().unwrap());

msg::StatRes::create(
builder,
&msg::StatResArgs {
is_file: file_type.is_file(),
is_symlink: file_type.is_symlink(),
len: metadata.len(),
modified: to_seconds!(metadata.modified()),
accessed: to_seconds!(metadata.accessed()),
created: to_seconds!(metadata.created()),
name: Some(name),
mode: get_mode(&metadata.permissions()),
has_mode: cfg!(target_family = "unix"),
},
)

json!({
"isFile": file_type.is_file(),
"isSymlink": file_type.is_symlink(),
"len": metadata.len(),
"modified": to_seconds!(metadata.modified()),
"accessed": to_seconds!(metadata.accessed()),
"created": to_seconds!(metadata.created()),
"mode": get_mode(&metadata.permissions()),
"name": entry.file_name().to_str().unwrap(),
"hasMode": cfg!(target_family = "unix"), // false on windows,
})
})
.collect();

let entries = builder.create_vector(&entries);
let inner = msg::ReadDirRes::create(
builder,
&msg::ReadDirResArgs {
entries: Some(entries),
},
);
Ok(serialize_response(
cmd_id,
builder,
msg::BaseArgs {
inner: Some(inner.as_union_value()),
inner_type: msg::Any::ReadDirRes,
..Default::default()
},
))
Ok(json!({ "entries": entries }))
})
}

Expand Down
14 changes: 14 additions & 0 deletions cli/ops/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ pub const OP_CHDIR: OpId = 42;
pub const OP_MKDIR: OpId = 43;
pub const OP_CHMOD: OpId = 44;
pub const OP_CHOWN: OpId = 45;
pub const OP_REMOVE: OpId = 46;
pub const OP_COPY_FILE: OpId = 47;
pub const OP_STAT: OpId = 48;
pub const OP_READ_DIR: OpId = 49;

pub fn dispatch(
state: &ThreadSafeState,
Expand Down Expand Up @@ -258,6 +262,16 @@ pub fn dispatch(
OP_CHOWN => {
dispatch_json::dispatch(fs::op_chown, state, control, zero_copy)
}
OP_REMOVE => {
dispatch_json::dispatch(fs::op_remove, state, control, zero_copy)
}
OP_COPY_FILE => {
dispatch_json::dispatch(fs::op_copy_file, state, control, zero_copy)
}
OP_STAT => dispatch_json::dispatch(fs::op_stat, state, control, zero_copy),
OP_READ_DIR => {
dispatch_json::dispatch(fs::op_read_dir, state, control, zero_copy)
}
OP_FLATBUFFER => dispatch_flatbuffers::dispatch(state, control, zero_copy),
_ => panic!("bad op_id"),
};
Expand Down
Loading

0 comments on commit d32dfd6

Please sign in to comment.