1
1
mirror of https://github.com/wez/wezterm.git synced 2024-11-23 06:54:45 +03:00

Finish refactoring names of methods based on wez feedback

This commit is contained in:
Chip Senkbeil 2021-10-03 12:05:03 -05:00 committed by Wez Furlong
parent c3516341cb
commit d15789d2c0
5 changed files with 456 additions and 447 deletions

View File

@ -394,141 +394,141 @@ impl SessionInner {
}
Ok(true)
}
SessionRequest::Sftp(SftpRequest::OpenMode(open_mode)) => {
if let Err(err) = self.open_mode(&sess, &open_mode) {
log::error!("{:?} -> error: {:#}", open_mode, err);
SessionRequest::Sftp(SftpRequest::OpenWithMode(msg)) => {
if let Err(err) = self.open_with_mode(&sess, &msg) {
log::error!("{:?} -> error: {:#}", msg, err);
}
Ok(true)
}
SessionRequest::Sftp(SftpRequest::Open(open)) => {
if let Err(err) = self.open(&sess, &open) {
log::error!("{:?} -> error: {:#}", open, err);
SessionRequest::Sftp(SftpRequest::Open(msg)) => {
if let Err(err) = self.open(&sess, &msg) {
log::error!("{:?} -> error: {:#}", msg, err);
}
Ok(true)
}
SessionRequest::Sftp(SftpRequest::Create(create)) => {
if let Err(err) = self.create(&sess, &create) {
log::error!("{:?} -> error: {:#}", create, err);
SessionRequest::Sftp(SftpRequest::Create(msg)) => {
if let Err(err) = self.create(&sess, &msg) {
log::error!("{:?} -> error: {:#}", msg, err);
}
Ok(true)
}
SessionRequest::Sftp(SftpRequest::Opendir(opendir)) => {
if let Err(err) = self.opendir(&sess, &opendir) {
log::error!("{:?} -> error: {:#}", opendir, err);
SessionRequest::Sftp(SftpRequest::OpenDir(msg)) => {
if let Err(err) = self.open_dir(&sess, &msg) {
log::error!("{:?} -> error: {:#}", msg, err);
}
Ok(true)
}
SessionRequest::Sftp(SftpRequest::File(FileRequest::Write(write_file))) => {
if let Err(err) = self.write_file(&sess, &write_file) {
log::error!("{:?} -> error: {:#}", write_file, err);
SessionRequest::Sftp(SftpRequest::File(FileRequest::Write(msg))) => {
if let Err(err) = self.write_file(&sess, &msg) {
log::error!("{:?} -> error: {:#}", msg, err);
}
Ok(true)
}
SessionRequest::Sftp(SftpRequest::File(FileRequest::Read(read_file))) => {
if let Err(err) = self.read_file(&sess, &read_file) {
log::error!("{:?} -> error: {:#}", read_file, err);
SessionRequest::Sftp(SftpRequest::File(FileRequest::Read(msg))) => {
if let Err(err) = self.read_file(&sess, &msg) {
log::error!("{:?} -> error: {:#}", msg, err);
}
Ok(true)
}
SessionRequest::Sftp(SftpRequest::File(FileRequest::Close(close_file))) => {
if let Err(err) = self.close_file(&sess, &close_file) {
log::error!("{:?} -> error: {:#}", close_file, err);
SessionRequest::Sftp(SftpRequest::File(FileRequest::Close(msg))) => {
if let Err(err) = self.close_file(&sess, &msg) {
log::error!("{:?} -> error: {:#}", msg, err);
}
Ok(true)
}
SessionRequest::Sftp(SftpRequest::File(FileRequest::Flush(flush_file))) => {
if let Err(err) = self.flush_file(&sess, &flush_file) {
log::error!("{:?} -> error: {:#}", flush_file, err);
SessionRequest::Sftp(SftpRequest::File(FileRequest::Flush(msg))) => {
if let Err(err) = self.flush_file(&sess, &msg) {
log::error!("{:?} -> error: {:#}", msg, err);
}
Ok(true)
}
SessionRequest::Sftp(SftpRequest::File(FileRequest::Setstat(setstat_file))) => {
if let Err(err) = self.setstat_file(&sess, &setstat_file) {
log::error!("{:?} -> error: {:#}", setstat_file, err);
SessionRequest::Sftp(SftpRequest::File(FileRequest::SetMetadata(msg))) => {
if let Err(err) = self.set_metadata_file(&sess, &msg) {
log::error!("{:?} -> error: {:#}", msg, err);
}
Ok(true)
}
SessionRequest::Sftp(SftpRequest::File(FileRequest::Stat(stat_file))) => {
if let Err(err) = self.stat_file(&sess, &stat_file) {
log::error!("{:?} -> error: {:#}", stat_file, err);
SessionRequest::Sftp(SftpRequest::File(FileRequest::Metadata(msg))) => {
if let Err(err) = self.metadata_file(&sess, &msg) {
log::error!("{:?} -> error: {:#}", msg, err);
}
Ok(true)
}
SessionRequest::Sftp(SftpRequest::File(FileRequest::Readdir(readdir_file))) => {
if let Err(err) = self.readdir_file(&sess, &readdir_file) {
log::error!("{:?} -> error: {:#}", readdir_file, err);
SessionRequest::Sftp(SftpRequest::File(FileRequest::ReadDir(msg))) => {
if let Err(err) = self.read_dir_file(&sess, &msg) {
log::error!("{:?} -> error: {:#}", msg, err);
}
Ok(true)
}
SessionRequest::Sftp(SftpRequest::File(FileRequest::Fsync(fsync_file))) => {
if let Err(err) = self.fsync_file(&sess, &fsync_file) {
log::error!("{:?} -> error: {:#}", fsync_file, err);
SessionRequest::Sftp(SftpRequest::File(FileRequest::Fsync(msg))) => {
if let Err(err) = self.fsync_file(&sess, &msg) {
log::error!("{:?} -> error: {:#}", msg, err);
}
Ok(true)
}
SessionRequest::Sftp(SftpRequest::Readdir(readdir)) => {
if let Err(err) = self.readdir(&sess, &readdir) {
log::error!("{:?} -> error: {:#}", readdir, err);
SessionRequest::Sftp(SftpRequest::ReadDir(msg)) => {
if let Err(err) = self.read_dir(&sess, &msg) {
log::error!("{:?} -> error: {:#}", msg, err);
}
Ok(true)
}
SessionRequest::Sftp(SftpRequest::Mkdir(mkdir)) => {
if let Err(err) = self.mkdir(&sess, &mkdir) {
log::error!("{:?} -> error: {:#}", mkdir, err);
SessionRequest::Sftp(SftpRequest::CreateDir(msg)) => {
if let Err(err) = self.create_dir(&sess, &msg) {
log::error!("{:?} -> error: {:#}", msg, err);
}
Ok(true)
}
SessionRequest::Sftp(SftpRequest::Rmdir(rmdir)) => {
if let Err(err) = self.rmdir(&sess, &rmdir) {
log::error!("{:?} -> error: {:#}", rmdir, err);
SessionRequest::Sftp(SftpRequest::RemoveDir(msg)) => {
if let Err(err) = self.remove_dir(&sess, &msg) {
log::error!("{:?} -> error: {:#}", msg, err);
}
Ok(true)
}
SessionRequest::Sftp(SftpRequest::Stat(stat)) => {
if let Err(err) = self.stat(&sess, &stat) {
log::error!("{:?} -> error: {:#}", stat, err);
SessionRequest::Sftp(SftpRequest::Metadata(msg)) => {
if let Err(err) = self.metadata(&sess, &msg) {
log::error!("{:?} -> error: {:#}", msg, err);
}
Ok(true)
}
SessionRequest::Sftp(SftpRequest::Lstat(lstat)) => {
if let Err(err) = self.lstat(&sess, &lstat) {
log::error!("{:?} -> error: {:#}", lstat, err);
SessionRequest::Sftp(SftpRequest::SymlinkMetadata(msg)) => {
if let Err(err) = self.symlink_metadata(&sess, &msg) {
log::error!("{:?} -> error: {:#}", msg, err);
}
Ok(true)
}
SessionRequest::Sftp(SftpRequest::Setstat(setstat)) => {
if let Err(err) = self.setstat(&sess, &setstat) {
log::error!("{:?} -> error: {:#}", setstat, err);
SessionRequest::Sftp(SftpRequest::SetMetadata(msg)) => {
if let Err(err) = self.set_metadata(&sess, &msg) {
log::error!("{:?} -> error: {:#}", msg, err);
}
Ok(true)
}
SessionRequest::Sftp(SftpRequest::Symlink(symlink)) => {
if let Err(err) = self.symlink(&sess, &symlink) {
log::error!("{:?} -> error: {:#}", symlink, err);
SessionRequest::Sftp(SftpRequest::Symlink(msg)) => {
if let Err(err) = self.symlink(&sess, &msg) {
log::error!("{:?} -> error: {:#}", msg, err);
}
Ok(true)
}
SessionRequest::Sftp(SftpRequest::Readlink(readlink)) => {
if let Err(err) = self.readlink(&sess, &readlink) {
log::error!("{:?} -> error: {:#}", readlink, err);
SessionRequest::Sftp(SftpRequest::ReadLink(msg)) => {
if let Err(err) = self.read_link(&sess, &msg) {
log::error!("{:?} -> error: {:#}", msg, err);
}
Ok(true)
}
SessionRequest::Sftp(SftpRequest::Realpath(realpath)) => {
if let Err(err) = self.realpath(&sess, &realpath) {
log::error!("{:?} -> error: {:#}", realpath, err);
SessionRequest::Sftp(SftpRequest::Canonicalize(msg)) => {
if let Err(err) = self.canonicalize(&sess, &msg) {
log::error!("{:?} -> error: {:#}", msg, err);
}
Ok(true)
}
SessionRequest::Sftp(SftpRequest::Rename(rename)) => {
if let Err(err) = self.rename(&sess, &rename) {
log::error!("{:?} -> error: {:#}", rename, err);
SessionRequest::Sftp(SftpRequest::Rename(msg)) => {
if let Err(err) = self.rename(&sess, &msg) {
log::error!("{:?} -> error: {:#}", msg, err);
}
Ok(true)
}
SessionRequest::Sftp(SftpRequest::Unlink(unlink)) => {
if let Err(err) = self.unlink(&sess, &unlink) {
log::error!("{:?} -> error: {:#}", unlink, err);
SessionRequest::Sftp(SftpRequest::RemoveFile(msg)) => {
if let Err(err) = self.remove_file(&sess, &msg) {
log::error!("{:?} -> error: {:#}", msg, err);
}
Ok(true)
}
@ -622,24 +622,24 @@ impl SessionInner {
pub fn open_with_mode(
&mut self,
sess: &ssh2::Session,
open_mode: &sftp::OpenMode,
msg: &sftp::OpenWithMode,
) -> anyhow::Result<()> {
let flags: ssh2::OpenFlags = open_mode.opts.into();
let mode = open_mode.opts.mode;
let open_type: ssh2::OpenType = open_mode.opts.ty.into();
let flags: ssh2::OpenFlags = msg.opts.into();
let mode = msg.opts.mode;
let open_type: ssh2::OpenType = msg.opts.ty.into();
let result = self.init_sftp(sess).and_then(|sftp| {
sftp.open_mode(open_mode.filename.as_path(), flags, mode, open_type)
sftp.open_mode(msg.filename.as_path(), flags, mode, open_type)
.map_err(SftpChannelError::from)
});
match result {
Ok(ssh_file) => {
let (file_id, file) = self.make_file();
open_mode.reply.try_send(Ok(file))?;
msg.reply.try_send(Ok(file))?;
self.files.insert(file_id, ssh_file);
}
Err(x) => open_mode.reply.try_send(Err(x))?,
Err(x) => msg.reply.try_send(Err(x))?,
}
Ok(())
@ -648,19 +648,19 @@ impl SessionInner {
/// Helper to open a file in the `Read` mode.
///
/// See [`Sftp::open`] for more information.
pub fn open(&mut self, sess: &ssh2::Session, open: &sftp::Open) -> anyhow::Result<()> {
pub fn open(&mut self, sess: &ssh2::Session, msg: &sftp::Open) -> anyhow::Result<()> {
let result = self.init_sftp(sess).and_then(|sftp| {
sftp.open(open.filename.as_path())
sftp.open(msg.filename.as_path())
.map_err(SftpChannelError::from)
});
match result {
Ok(ssh_file) => {
let (file_id, file) = self.make_file();
open.reply.try_send(Ok(file))?;
msg.reply.try_send(Ok(file))?;
self.files.insert(file_id, ssh_file);
}
Err(x) => open.reply.try_send(Err(x))?,
Err(x) => msg.reply.try_send(Err(x))?,
}
Ok(())
@ -669,19 +669,19 @@ impl SessionInner {
/// Helper to create a file in write-only mode with truncation.
///
/// See [`Sftp::create`] for more information.
pub fn create(&mut self, sess: &ssh2::Session, create: &sftp::Create) -> anyhow::Result<()> {
pub fn create(&mut self, sess: &ssh2::Session, msg: &sftp::Create) -> anyhow::Result<()> {
let result = self.init_sftp(sess).and_then(|sftp| {
sftp.create(create.filename.as_path())
sftp.create(msg.filename.as_path())
.map_err(SftpChannelError::from)
});
match result {
Ok(ssh_file) => {
let (file_id, file) = self.make_file();
create.reply.try_send(Ok(file))?;
msg.reply.try_send(Ok(file))?;
self.files.insert(file_id, ssh_file);
}
Err(x) => create.reply.try_send(Err(x))?,
Err(x) => msg.reply.try_send(Err(x))?,
}
Ok(())
@ -690,19 +690,19 @@ impl SessionInner {
/// Helper to open a directory for reading its contents.
///
/// See [`Sftp::opendir`] for more information.
pub fn opendir(&mut self, sess: &ssh2::Session, opendir: &sftp::Opendir) -> anyhow::Result<()> {
pub fn open_dir(&mut self, sess: &ssh2::Session, msg: &sftp::OpenDir) -> anyhow::Result<()> {
let result = self.init_sftp(sess).and_then(|sftp| {
sftp.opendir(opendir.filename.as_path())
sftp.opendir(msg.filename.as_path())
.map_err(SftpChannelError::from)
});
match result {
Ok(ssh_file) => {
let (file_id, file) = self.make_file();
opendir.reply.try_send(Ok(file))?;
msg.reply.try_send(Ok(file))?;
self.files.insert(file_id, ssh_file);
}
Err(x) => opendir.reply.try_send(Err(x))?,
Err(x) => msg.reply.try_send(Err(x))?,
}
Ok(())
@ -717,16 +717,12 @@ impl SessionInner {
}
/// Writes to a loaded file.
fn write_file(
&mut self,
_sess: &ssh2::Session,
write_file: &sftp::WriteFile,
) -> anyhow::Result<()> {
fn write_file(&mut self, _sess: &ssh2::Session, msg: &sftp::WriteFile) -> anyhow::Result<()> {
let sftp::WriteFile {
file_id,
data,
reply,
} = write_file;
} = msg;
if let Some(file) = self.files.get_mut(file_id) {
let result = file.write_all(data).map_err(SftpChannelError::from);
@ -737,16 +733,12 @@ impl SessionInner {
}
/// Reads from a loaded file.
fn read_file(
&mut self,
_sess: &ssh2::Session,
read_file: &sftp::ReadFile,
) -> anyhow::Result<()> {
fn read_file(&mut self, _sess: &ssh2::Session, msg: &sftp::ReadFile) -> anyhow::Result<()> {
let sftp::ReadFile {
file_id,
max_bytes,
reply,
} = read_file;
} = msg;
if let Some(file) = self.files.get_mut(file_id) {
// TODO: Move this somewhere to avoid re-allocating buffer
@ -764,42 +756,34 @@ impl SessionInner {
}
/// Closes a file and removes it from the internal memory.
fn close_file(
&mut self,
_sess: &ssh2::Session,
close_file: &sftp::CloseFile,
) -> anyhow::Result<()> {
self.files.remove(&close_file.file_id);
close_file.reply.try_send(Ok(()))?;
fn close_file(&mut self, _sess: &ssh2::Session, msg: &sftp::CloseFile) -> anyhow::Result<()> {
self.files.remove(&msg.file_id);
msg.reply.try_send(Ok(()))?;
Ok(())
}
/// Flushes a file.
fn flush_file(
&mut self,
_sess: &ssh2::Session,
flush_file: &sftp::FlushFile,
) -> anyhow::Result<()> {
if let Some(file) = self.files.get_mut(&flush_file.file_id) {
fn flush_file(&mut self, _sess: &ssh2::Session, msg: &sftp::FlushFile) -> anyhow::Result<()> {
if let Some(file) = self.files.get_mut(&msg.file_id) {
let result = file.flush().map_err(SftpChannelError::from);
flush_file.reply.try_send(result)?;
msg.reply.try_send(result)?;
}
Ok(())
}
/// Sets file stat.
fn setstat_file(
/// Sets file metadata.
fn set_metadata_file(
&mut self,
_sess: &ssh2::Session,
setstat_file: &sftp::SetstatFile,
msg: &sftp::SetMetadataFile,
) -> anyhow::Result<()> {
let sftp::SetstatFile {
let sftp::SetMetadataFile {
file_id,
metadata,
reply,
} = setstat_file;
} = msg;
if let Some(file) = self.files.get_mut(file_id) {
let result = file
@ -812,34 +796,34 @@ impl SessionInner {
}
/// Gets file stat.
fn stat_file(
fn metadata_file(
&mut self,
_sess: &ssh2::Session,
stat_file: &sftp::StatFile,
msg: &sftp::MetadataFile,
) -> anyhow::Result<()> {
if let Some(file) = self.files.get_mut(&stat_file.file_id) {
if let Some(file) = self.files.get_mut(&msg.file_id) {
let result = file
.stat()
.map(Metadata::from)
.map_err(SftpChannelError::from);
stat_file.reply.try_send(result)?;
msg.reply.try_send(result)?;
}
Ok(())
}
/// Performs readdir for file.
fn readdir_file(
fn read_dir_file(
&mut self,
_sess: &ssh2::Session,
readdir_file: &sftp::ReaddirFile,
msg: &sftp::ReadDirFile,
) -> anyhow::Result<()> {
if let Some(file) = self.files.get_mut(&readdir_file.file_id) {
if let Some(file) = self.files.get_mut(&msg.file_id) {
let result = file
.readdir()
.map(|(path, stat)| (path, Metadata::from(stat)))
.map_err(SftpChannelError::from);
readdir_file.reply.try_send(result)?;
msg.reply.try_send(result)?;
}
Ok(())
@ -862,9 +846,9 @@ impl SessionInner {
/// Convenience function to read the files in a directory.
///
/// See [`Sftp::readdir`] for more information.
pub fn readdir(&mut self, sess: &ssh2::Session, readdir: &sftp::Readdir) -> anyhow::Result<()> {
pub fn read_dir(&mut self, sess: &ssh2::Session, msg: &sftp::ReadDir) -> anyhow::Result<()> {
let result = self.init_sftp(sess).and_then(|sftp| {
sftp.readdir(readdir.filename.as_path())
sftp.readdir(msg.filename.as_path())
.map(|entries| {
entries
.into_iter()
@ -873,7 +857,7 @@ impl SessionInner {
})
.map_err(SftpChannelError::from)
});
readdir.reply.try_send(result)?;
msg.reply.try_send(result)?;
Ok(())
}
@ -881,12 +865,16 @@ impl SessionInner {
/// Create a directory on the remote filesystem.
///
/// See [`Sftp::rmdir`] for more information.
pub fn mkdir(&mut self, sess: &ssh2::Session, mkdir: &sftp::Mkdir) -> anyhow::Result<()> {
pub fn create_dir(
&mut self,
sess: &ssh2::Session,
msg: &sftp::CreateDir,
) -> anyhow::Result<()> {
let result = self.init_sftp(sess).and_then(|sftp| {
sftp.mkdir(mkdir.filename.as_path(), mkdir.mode)
sftp.mkdir(msg.filename.as_path(), msg.mode)
.map_err(SftpChannelError::from)
});
mkdir.reply.try_send(result)?;
msg.reply.try_send(result)?;
Ok(())
}
@ -894,12 +882,16 @@ impl SessionInner {
/// Remove a directory from the remote filesystem.
///
/// See [`Sftp::rmdir`] for more information.
pub fn rmdir(&mut self, sess: &ssh2::Session, rmdir: &sftp::Rmdir) -> anyhow::Result<()> {
pub fn remove_dir(
&mut self,
sess: &ssh2::Session,
msg: &sftp::RemoveDir,
) -> anyhow::Result<()> {
let result = self.init_sftp(sess).and_then(|sftp| {
sftp.rmdir(rmdir.filename.as_path())
sftp.rmdir(msg.filename.as_path())
.map_err(SftpChannelError::from)
});
rmdir.reply.try_send(result)?;
msg.reply.try_send(result)?;
Ok(())
}
@ -907,13 +899,17 @@ impl SessionInner {
/// Get the metadata for a file, performed by stat(2).
///
/// See [`Sftp::stat`] for more information.
pub fn stat(&mut self, sess: &ssh2::Session, stat: &sftp::Stat) -> anyhow::Result<()> {
pub fn metadata(
&mut self,
sess: &ssh2::Session,
msg: &sftp::GetMetadata,
) -> anyhow::Result<()> {
let result = self.init_sftp(sess).and_then(|sftp| {
sftp.stat(stat.filename.as_path())
sftp.stat(msg.filename.as_path())
.map(Metadata::from)
.map_err(SftpChannelError::from)
});
stat.reply.try_send(result)?;
msg.reply.try_send(result)?;
Ok(())
}
@ -921,13 +917,17 @@ impl SessionInner {
/// Get the metadata for a file, performed by lstat(2).
///
/// See [`Sftp::lstat`] for more information.
pub fn lstat(&mut self, sess: &ssh2::Session, lstat: &sftp::Lstat) -> anyhow::Result<()> {
pub fn symlink_metadata(
&mut self,
sess: &ssh2::Session,
msg: &sftp::SymlinkMetadata,
) -> anyhow::Result<()> {
let result = self.init_sftp(sess).and_then(|sftp| {
sftp.lstat(lstat.filename.as_path())
sftp.lstat(msg.filename.as_path())
.map(Metadata::from)
.map_err(SftpChannelError::from)
});
lstat.reply.try_send(result)?;
msg.reply.try_send(result)?;
Ok(())
}
@ -935,12 +935,16 @@ impl SessionInner {
/// Set the metadata for a file.
///
/// See [`Sftp::setstat`] for more information.
pub fn setstat(&mut self, sess: &ssh2::Session, setstat: &sftp::Setstat) -> anyhow::Result<()> {
pub fn set_metadata(
&mut self,
sess: &ssh2::Session,
msg: &sftp::SetMetadata,
) -> anyhow::Result<()> {
let result = self.init_sftp(sess).and_then(|sftp| {
sftp.setstat(setstat.filename.as_path(), setstat.metadata.into())
sftp.setstat(msg.filename.as_path(), msg.metadata.into())
.map_err(SftpChannelError::from)
});
setstat.reply.try_send(result)?;
msg.reply.try_send(result)?;
Ok(())
}
@ -948,12 +952,12 @@ impl SessionInner {
/// Create symlink at `target` pointing at `path`.
///
/// See [`Sftp::symlink`] for more information.
pub fn symlink(&mut self, sess: &ssh2::Session, symlink: &sftp::Symlink) -> anyhow::Result<()> {
pub fn symlink(&mut self, sess: &ssh2::Session, msg: &sftp::Symlink) -> anyhow::Result<()> {
let result = self.init_sftp(sess).and_then(|sftp| {
sftp.symlink(symlink.path.as_path(), symlink.target.as_path())
sftp.symlink(msg.path.as_path(), msg.target.as_path())
.map_err(SftpChannelError::from)
});
symlink.reply.try_send(result)?;
msg.reply.try_send(result)?;
Ok(())
}
@ -961,16 +965,12 @@ impl SessionInner {
/// Read a symlink at `path`.
///
/// See [`Sftp::readlink`] for more information.
pub fn readlink(
&mut self,
sess: &ssh2::Session,
readlink: &sftp::Readlink,
) -> anyhow::Result<()> {
pub fn read_link(&mut self, sess: &ssh2::Session, msg: &sftp::ReadLink) -> anyhow::Result<()> {
let result = self.init_sftp(sess).and_then(|sftp| {
sftp.readlink(readlink.path.as_path())
sftp.readlink(msg.path.as_path())
.map_err(SftpChannelError::from)
});
readlink.reply.try_send(result)?;
msg.reply.try_send(result)?;
Ok(())
}
@ -978,16 +978,16 @@ impl SessionInner {
/// Resolve the real path for `path`.
///
/// See [`Sftp::realpath`] for more information.
pub fn realpath(
pub fn canonicalize(
&mut self,
sess: &ssh2::Session,
realpath: &sftp::Realpath,
msg: &sftp::Canonicalize,
) -> anyhow::Result<()> {
let result = self.init_sftp(sess).and_then(|sftp| {
sftp.realpath(realpath.path.as_path())
sftp.realpath(msg.path.as_path())
.map_err(SftpChannelError::from)
});
realpath.reply.try_send(result)?;
msg.reply.try_send(result)?;
Ok(())
}
@ -995,16 +995,12 @@ impl SessionInner {
/// Rename the filesystem object on the remote filesystem.
///
/// See [`Sftp::rename`] for more information.
pub fn rename(&mut self, sess: &ssh2::Session, rename: &sftp::Rename) -> anyhow::Result<()> {
pub fn rename(&mut self, sess: &ssh2::Session, msg: &sftp::Rename) -> anyhow::Result<()> {
let result = self.init_sftp(sess).and_then(|sftp| {
sftp.rename(
rename.src.as_path(),
rename.dst.as_path(),
Some(rename.opts.into()),
)
sftp.rename(msg.src.as_path(), msg.dst.as_path(), Some(msg.opts.into()))
.map_err(SftpChannelError::from)
});
rename.reply.try_send(result)?;
msg.reply.try_send(result)?;
Ok(())
}
@ -1012,12 +1008,16 @@ impl SessionInner {
/// Remove a file on the remote filesystem.
///
/// See [`Sftp::unlink`] for more information.
pub fn unlink(&mut self, sess: &ssh2::Session, unlink: &sftp::Unlink) -> anyhow::Result<()> {
pub fn remove_file(
&mut self,
sess: &ssh2::Session,
msg: &sftp::RemoveFile,
) -> anyhow::Result<()> {
let result = self.init_sftp(sess).and_then(|sftp| {
sftp.unlink(unlink.file.as_path())
sftp.unlink(msg.file.as_path())
.map_err(SftpChannelError::from)
});
unlink.reply.try_send(result)?;
msg.reply.try_send(result)?;
Ok(())
}

View File

@ -9,8 +9,8 @@ pub use error::{SftpError, SftpResult};
mod file;
pub use file::File;
pub(crate) use file::{
CloseFile, FileId, FileRequest, FlushFile, FsyncFile, ReadFile, ReaddirFile, SetstatFile,
StatFile, WriteFile,
CloseFile, FileId, FileRequest, FlushFile, FsyncFile, MetadataFile, ReadDirFile, ReadFile,
SetMetadataFile, WriteFile,
};
mod types;
@ -48,8 +48,6 @@ pub struct Sftp {
impl Sftp {
/// Open a handle to a file.
///
/// See [`Sftp::open_mode`] for more information.
pub async fn open_with_mode(
&self,
filename: impl Into<PathBuf>,
@ -58,11 +56,13 @@ impl Sftp {
let (reply, rx) = bounded(1);
self.tx
.send(SessionRequest::Sftp(SftpRequest::OpenMode(OpenMode {
.send(SessionRequest::Sftp(SftpRequest::OpenWithMode(
OpenWithMode {
filename: filename.into(),
opts,
reply,
})))
},
)))
.await?;
let mut result = rx.recv().await??;
result.initialize_sender(self.tx.clone());
@ -70,8 +70,6 @@ impl Sftp {
}
/// Helper to open a file in the `Read` mode.
///
/// See [`Sftp::open`] for more information.
pub async fn open(&self, filename: impl Into<PathBuf>) -> SftpChannelResult<File> {
let (reply, rx) = bounded(1);
self.tx
@ -86,8 +84,6 @@ impl Sftp {
}
/// Helper to create a file in write-only mode with truncation.
///
/// See [`Sftp::create`] for more information.
pub async fn create(&self, filename: impl Into<PathBuf>) -> SftpChannelResult<File> {
let (reply, rx) = bounded(1);
self.tx
@ -102,12 +98,10 @@ impl Sftp {
}
/// Helper to open a directory for reading its contents.
///
/// See [`Sftp::opendir`] for more information.
pub async fn open_dir(&self, filename: impl Into<PathBuf>) -> SftpChannelResult<File> {
let (reply, rx) = bounded(1);
self.tx
.send(SessionRequest::Sftp(SftpRequest::Opendir(Opendir {
.send(SessionRequest::Sftp(SftpRequest::OpenDir(OpenDir {
filename: filename.into(),
reply,
})))
@ -121,15 +115,13 @@ impl Sftp {
///
/// The returned paths are all joined with dirname when returned, and the paths . and .. are
/// filtered out of the returned list.
///
/// See [`Sftp::readdir`] for more information.
pub async fn read_dir(
&self,
filename: impl Into<PathBuf>,
) -> SftpChannelResult<Vec<(PathBuf, Metadata)>> {
let (reply, rx) = bounded(1);
self.tx
.send(SessionRequest::Sftp(SftpRequest::Readdir(Readdir {
.send(SessionRequest::Sftp(SftpRequest::ReadDir(ReadDir {
filename: filename.into(),
reply,
})))
@ -139,12 +131,14 @@ impl Sftp {
}
/// Create a directory on the remote filesystem.
///
/// See [`Sftp::rmdir`] for more information.
pub async fn create_dir(&self, filename: impl Into<PathBuf>, mode: i32) -> SftpChannelResult<()> {
pub async fn create_dir(
&self,
filename: impl Into<PathBuf>,
mode: i32,
) -> SftpChannelResult<()> {
let (reply, rx) = bounded(1);
self.tx
.send(SessionRequest::Sftp(SftpRequest::Mkdir(Mkdir {
.send(SessionRequest::Sftp(SftpRequest::CreateDir(CreateDir {
filename: filename.into(),
mode,
reply,
@ -155,12 +149,10 @@ impl Sftp {
}
/// Remove a directory from the remote filesystem.
///
/// See [`Sftp::rmdir`] for more information.
pub async fn remove_dir(&self, filename: impl Into<PathBuf>) -> SftpChannelResult<()> {
let (reply, rx) = bounded(1);
self.tx
.send(SessionRequest::Sftp(SftpRequest::Rmdir(Rmdir {
.send(SessionRequest::Sftp(SftpRequest::RemoveDir(RemoveDir {
filename: filename.into(),
reply,
})))
@ -170,12 +162,10 @@ impl Sftp {
}
/// Get the metadata for a file, performed by stat(2).
///
/// See [`Sftp::stat`] for more information.
pub async fn metadata(&self, filename: impl Into<PathBuf>) -> SftpChannelResult<Metadata> {
let (reply, rx) = bounded(1);
self.tx
.send(SessionRequest::Sftp(SftpRequest::Stat(Stat {
.send(SessionRequest::Sftp(SftpRequest::Metadata(GetMetadata {
filename: filename.into(),
reply,
})))
@ -185,23 +175,24 @@ impl Sftp {
}
/// Get the metadata for a file, performed by lstat(2).
///
/// See [`Sftp::lstat`] for more information.
pub async fn symlink_metadata(&self, filename: impl Into<PathBuf>) -> SftpChannelResult<Metadata> {
pub async fn symlink_metadata(
&self,
filename: impl Into<PathBuf>,
) -> SftpChannelResult<Metadata> {
let (reply, rx) = bounded(1);
self.tx
.send(SessionRequest::Sftp(SftpRequest::Lstat(Lstat {
.send(SessionRequest::Sftp(SftpRequest::SymlinkMetadata(
SymlinkMetadata {
filename: filename.into(),
reply,
})))
},
)))
.await?;
let result = rx.recv().await??;
Ok(result)
}
/// Set the metadata for a file.
///
/// See [`Sftp::setstat`] for more information.
pub async fn set_metadata(
&self,
filename: impl Into<PathBuf>,
@ -209,19 +200,19 @@ impl Sftp {
) -> SftpChannelResult<()> {
let (reply, rx) = bounded(1);
self.tx
.send(SessionRequest::Sftp(SftpRequest::Setstat(Setstat {
.send(SessionRequest::Sftp(SftpRequest::SetMetadata(
SetMetadata {
filename: filename.into(),
metadata,
reply,
})))
},
)))
.await?;
let result = rx.recv().await??;
Ok(result)
}
/// Create symlink at `target` pointing at `path`.
///
/// See [`Sftp::symlink`] for more information.
pub async fn symlink(
&self,
path: impl Into<PathBuf>,
@ -240,12 +231,10 @@ impl Sftp {
}
/// Read a symlink at `path`.
///
/// See [`Sftp::readlink`] for more information.
pub async fn read_link(&self, path: impl Into<PathBuf>) -> SftpChannelResult<PathBuf> {
let (reply, rx) = bounded(1);
self.tx
.send(SessionRequest::Sftp(SftpRequest::Readlink(Readlink {
.send(SessionRequest::Sftp(SftpRequest::ReadLink(ReadLink {
path: path.into(),
reply,
})))
@ -255,23 +244,21 @@ impl Sftp {
}
/// Resolve the real path for `path`.
///
/// See [`Sftp::realpath`] for more information.
pub async fn canonicalize(&self, path: impl Into<PathBuf>) -> SftpChannelResult<PathBuf> {
let (reply, rx) = bounded(1);
self.tx
.send(SessionRequest::Sftp(SftpRequest::Realpath(Realpath {
.send(SessionRequest::Sftp(SftpRequest::Canonicalize(
Canonicalize {
path: path.into(),
reply,
})))
},
)))
.await?;
let result = rx.recv().await??;
Ok(result)
}
/// Rename the filesystem object on the remote filesystem.
///
/// See [`Sftp::rename`] for more information.
pub async fn rename(
&self,
src: impl Into<PathBuf>,
@ -292,12 +279,10 @@ impl Sftp {
}
/// Remove a file on the remote filesystem.
///
/// See [`Sftp::unlink`] for more information.
pub async fn remove_file(&self, file: impl Into<PathBuf>) -> SftpChannelResult<()> {
let (reply, rx) = bounded(1);
self.tx
.send(SessionRequest::Sftp(SftpRequest::Unlink(Unlink {
.send(SessionRequest::Sftp(SftpRequest::RemoveFile(RemoveFile {
file: file.into(),
reply,
})))
@ -309,28 +294,28 @@ impl Sftp {
#[derive(Debug)]
pub(crate) enum SftpRequest {
OpenMode(OpenMode),
OpenWithMode(OpenWithMode),
Open(Open),
Create(Create),
Opendir(Opendir),
Readdir(Readdir),
Mkdir(Mkdir),
Rmdir(Rmdir),
Stat(Stat),
Lstat(Lstat),
Setstat(Setstat),
OpenDir(OpenDir),
ReadDir(ReadDir),
CreateDir(CreateDir),
RemoveDir(RemoveDir),
Metadata(GetMetadata),
SymlinkMetadata(SymlinkMetadata),
SetMetadata(SetMetadata),
Symlink(Symlink),
Readlink(Readlink),
Realpath(Realpath),
ReadLink(ReadLink),
Canonicalize(Canonicalize),
Rename(Rename),
Unlink(Unlink),
RemoveFile(RemoveFile),
/// Specialized type for file-based operations
File(FileRequest),
}
#[derive(Debug)]
pub(crate) struct OpenMode {
pub(crate) struct OpenWithMode {
pub filename: PathBuf,
pub opts: OpenOptions,
pub reply: Sender<SftpChannelResult<File>>,
@ -349,44 +334,44 @@ pub(crate) struct Create {
}
#[derive(Debug)]
pub(crate) struct Opendir {
pub(crate) struct OpenDir {
pub filename: PathBuf,
pub reply: Sender<SftpChannelResult<File>>,
}
#[derive(Debug)]
pub(crate) struct Readdir {
pub(crate) struct ReadDir {
pub filename: PathBuf,
pub reply: Sender<SftpChannelResult<Vec<(PathBuf, Metadata)>>>,
}
#[derive(Debug)]
pub(crate) struct Mkdir {
pub(crate) struct CreateDir {
pub filename: PathBuf,
pub mode: i32,
pub reply: Sender<SftpChannelResult<()>>,
}
#[derive(Debug)]
pub(crate) struct Rmdir {
pub(crate) struct RemoveDir {
pub filename: PathBuf,
pub reply: Sender<SftpChannelResult<()>>,
}
#[derive(Debug)]
pub(crate) struct Stat {
pub(crate) struct GetMetadata {
pub filename: PathBuf,
pub reply: Sender<SftpChannelResult<Metadata>>,
}
#[derive(Debug)]
pub(crate) struct Lstat {
pub(crate) struct SymlinkMetadata {
pub filename: PathBuf,
pub reply: Sender<SftpChannelResult<Metadata>>,
}
#[derive(Debug)]
pub(crate) struct Setstat {
pub(crate) struct SetMetadata {
pub filename: PathBuf,
pub metadata: Metadata,
pub reply: Sender<SftpChannelResult<()>>,
@ -400,13 +385,13 @@ pub(crate) struct Symlink {
}
#[derive(Debug)]
pub(crate) struct Readlink {
pub(crate) struct ReadLink {
pub path: PathBuf,
pub reply: Sender<SftpChannelResult<PathBuf>>,
}
#[derive(Debug)]
pub(crate) struct Realpath {
pub(crate) struct Canonicalize {
pub path: PathBuf,
pub reply: Sender<SftpChannelResult<PathBuf>>,
}
@ -420,7 +405,7 @@ pub(crate) struct Rename {
}
#[derive(Debug)]
pub(crate) struct Unlink {
pub(crate) struct RemoveFile {
pub file: PathBuf,
pub reply: Sender<SftpChannelResult<()>>,
}

View File

@ -27,9 +27,9 @@ pub(crate) enum FileRequest {
Read(ReadFile),
Close(CloseFile),
Flush(FlushFile),
Setstat(SetstatFile),
Stat(StatFile),
Readdir(ReaddirFile),
SetMetadata(SetMetadataFile),
Metadata(MetadataFile),
ReadDir(ReadDirFile),
Fsync(FsyncFile),
}
@ -60,20 +60,20 @@ pub(crate) struct FlushFile {
}
#[derive(Debug)]
pub(crate) struct SetstatFile {
pub(crate) struct SetMetadataFile {
pub file_id: FileId,
pub metadata: Metadata,
pub reply: Sender<SftpChannelResult<()>>,
}
#[derive(Debug)]
pub(crate) struct StatFile {
pub(crate) struct MetadataFile {
pub file_id: FileId,
pub reply: Sender<SftpChannelResult<Metadata>>,
}
#[derive(Debug)]
pub(crate) struct ReaddirFile {
pub(crate) struct ReadDirFile {
pub file_id: FileId,
pub reply: Sender<SftpChannelResult<(PathBuf, Metadata)>>,
}
@ -129,7 +129,7 @@ impl File {
.as_ref()
.unwrap()
.send(SessionRequest::Sftp(SftpRequest::File(
FileRequest::Setstat(SetstatFile {
FileRequest::SetMetadata(SetMetadataFile {
file_id: self.file_id,
metadata,
reply,
@ -148,12 +148,12 @@ impl File {
self.tx
.as_ref()
.unwrap()
.send(SessionRequest::Sftp(SftpRequest::File(FileRequest::Stat(
StatFile {
.send(SessionRequest::Sftp(SftpRequest::File(
FileRequest::Metadata(MetadataFile {
file_id: self.file_id,
reply,
},
))))
}),
)))
.await?;
let result = rx.recv().await??;
Ok(result)
@ -176,7 +176,7 @@ impl File {
.as_ref()
.unwrap()
.send(SessionRequest::Sftp(SftpRequest::File(
FileRequest::Readdir(ReaddirFile {
FileRequest::ReadDir(ReadDirFile {
file_id: self.file_id,
reply,
}),

View File

@ -22,7 +22,7 @@ fn file_type_to_str(file_type: FileType) -> &'static str {
#[rstest]
#[smol_potat::test]
#[cfg_attr(not(any(target_os = "macos", target_os = "linux")), ignore)]
async fn readdir_should_return_list_of_directories_files_and_symlinks(#[future] session: Session) {
async fn read_dir_should_return_list_of_directories_files_and_symlinks(#[future] session: Session) {
let session: Session = session.await;
// $TEMP/dir1/
@ -47,7 +47,7 @@ async fn readdir_should_return_list_of_directories_files_and_symlinks(#[future]
let mut contents = session
.sftp()
.readdir(temp.path())
.read_dir(temp.path())
.await
.expect("Failed to read directory")
.into_iter()
@ -71,14 +71,14 @@ async fn readdir_should_return_list_of_directories_files_and_symlinks(#[future]
#[rstest]
#[smol_potat::test]
#[cfg_attr(not(any(target_os = "macos", target_os = "linux")), ignore)]
async fn mkdir_should_create_a_directory_on_the_remote_filesystem(#[future] session: Session) {
async fn create_dir_should_create_a_directory_on_the_remote_filesystem(#[future] session: Session) {
let session: Session = session.await;
let temp = TempDir::new().unwrap();
session
.sftp()
.mkdir(temp.child("dir").path(), 0o644)
.create_dir(temp.child("dir").path(), 0o644)
.await
.expect("Failed to create directory");
@ -89,7 +89,7 @@ async fn mkdir_should_create_a_directory_on_the_remote_filesystem(#[future] sess
#[rstest]
#[smol_potat::test]
#[cfg_attr(not(any(target_os = "macos", target_os = "linux")), ignore)]
async fn mkdir_should_return_error_if_unable_to_create_directory(#[future] session: Session) {
async fn create_dir_should_return_error_if_unable_to_create_directory(#[future] session: Session) {
let session: Session = session.await;
let temp = TempDir::new().unwrap();
@ -97,7 +97,7 @@ async fn mkdir_should_return_error_if_unable_to_create_directory(#[future] sessi
// Attempt to create a nested directory structure, which is not supported
let result = session
.sftp()
.mkdir(temp.child("dir").child("dir").path(), 0o644)
.create_dir(temp.child("dir").child("dir").path(), 0o644)
.await;
assert!(
result.is_err(),
@ -115,7 +115,7 @@ async fn mkdir_should_return_error_if_unable_to_create_directory(#[future] sessi
#[rstest]
#[smol_potat::test]
#[cfg_attr(not(any(target_os = "macos", target_os = "linux")), ignore)]
async fn rmdir_should_remove_a_remote_directory(#[future] session: Session) {
async fn remove_dir_should_remove_a_remote_directory(#[future] session: Session) {
let session: Session = session.await;
let temp = TempDir::new().unwrap();
@ -125,7 +125,7 @@ async fn rmdir_should_remove_a_remote_directory(#[future] session: Session) {
dir.create_dir_all().unwrap();
session
.sftp()
.rmdir(dir.path())
.remove_dir(dir.path())
.await
.expect("Failed to remove directory");
@ -136,13 +136,18 @@ async fn rmdir_should_remove_a_remote_directory(#[future] session: Session) {
#[rstest]
#[smol_potat::test]
#[cfg_attr(not(any(target_os = "macos", target_os = "linux")), ignore)]
async fn rmdir_should_return_an_error_if_failed_to_remove_directory(#[future] session: Session) {
async fn remove_dir_should_return_an_error_if_failed_to_remove_directory(
#[future] session: Session,
) {
let session: Session = session.await;
let temp = TempDir::new().unwrap();
// Attempt to remove a missing path
let result = session.sftp().rmdir(temp.child("missing-dir").path()).await;
let result = session
.sftp()
.remove_dir(temp.child("missing-dir").path())
.await;
assert!(
result.is_err(),
"Unexpectedly succeeded in removing missing directory: {:?}",
@ -154,7 +159,7 @@ async fn rmdir_should_return_an_error_if_failed_to_remove_directory(#[future] se
dir.create_dir_all().unwrap();
dir.child("file").touch().unwrap();
let result = session.sftp().rmdir(dir.path()).await;
let result = session.sftp().remove_dir(dir.path()).await;
assert!(
result.is_err(),
"Unexpectedly succeeded in removing non-empty directory: {:?}",
@ -167,7 +172,7 @@ async fn rmdir_should_return_an_error_if_failed_to_remove_directory(#[future] se
// Attempt to remove a file (not a directory)
let file = temp.child("file");
file.touch().unwrap();
let result = session.sftp().rmdir(file.path()).await;
let result = session.sftp().remove_dir(file.path()).await;
assert!(
result.is_err(),
"Unexpectedly succeeded in removing file: {:?}",
@ -181,47 +186,47 @@ async fn rmdir_should_return_an_error_if_failed_to_remove_directory(#[future] se
#[rstest]
#[smol_potat::test]
#[cfg_attr(not(any(target_os = "macos", target_os = "linux")), ignore)]
async fn stat_should_return_metadata_about_a_file(#[future] session: Session) {
async fn metadata_should_return_metadata_about_a_file(#[future] session: Session) {
let session: Session = session.await;
let temp = TempDir::new().unwrap();
let file = temp.child("file");
file.touch().unwrap();
let stat = session
let metadata = session
.sftp()
.stat(file.path())
.metadata(file.path())
.await
.expect("Failed to stat file");
.expect("Failed to get metadata for file");
// Verify that file stat makes sense
assert!(stat.is_file(), "Invalid file stat returned");
// Verify that file metadata makes sense
assert!(metadata.is_file(), "Invalid file metadata returned");
}
#[rstest]
#[smol_potat::test]
#[cfg_attr(not(any(target_os = "macos", target_os = "linux")), ignore)]
async fn stat_should_return_metadata_about_a_directory(#[future] session: Session) {
async fn metadata_should_return_metadata_about_a_directory(#[future] session: Session) {
let session: Session = session.await;
let temp = TempDir::new().unwrap();
let dir = temp.child("dir");
dir.create_dir_all().unwrap();
let stat = session
let metadata = session
.sftp()
.stat(dir.path())
.metadata(dir.path())
.await
.expect("Failed to stat dir");
.expect("Failed to get metadata for dir");
// Verify that file stat makes sense
assert!(stat.is_dir(), "Invalid file stat returned");
// Verify that file metadata makes sense
assert!(metadata.is_dir(), "Invalid file metadata returned");
}
#[rstest]
#[smol_potat::test]
#[cfg_attr(not(any(target_os = "macos", target_os = "linux")), ignore)]
async fn stat_should_return_metadata_about_the_file_pointed_to_by_a_symlink(
async fn metadata_should_return_metadata_about_the_file_pointed_to_by_a_symlink(
#[future] session: Session,
) {
let session: Session = session.await;
@ -235,20 +240,20 @@ async fn stat_should_return_metadata_about_the_file_pointed_to_by_a_symlink(
let metadata = session
.sftp()
.stat(link.path())
.metadata(link.path())
.await
.expect("Failed to stat symlink");
.expect("Failed to get metadata for symlink");
// Verify that file stat makes sense
assert!(metadata.is_file(), "Invalid file stat returned");
assert!(metadata.ty.is_file(), "Invalid file stat returned");
assert!(!metadata.ty.is_symlink(), "Invalid file stat returned");
// Verify that file metadata makes sense
assert!(metadata.is_file(), "Invalid file metadata returned");
assert!(metadata.ty.is_file(), "Invalid file metadata returned");
assert!(!metadata.ty.is_symlink(), "Invalid file metadata returned");
}
#[rstest]
#[smol_potat::test]
#[cfg_attr(not(any(target_os = "macos", target_os = "linux")), ignore)]
async fn stat_should_return_metadata_about_the_dir_pointed_to_by_a_symlink(
async fn metadata_should_return_metadata_about_the_dir_pointed_to_by_a_symlink(
#[future] session: Session,
) {
let session: Session = session.await;
@ -262,132 +267,141 @@ async fn stat_should_return_metadata_about_the_dir_pointed_to_by_a_symlink(
let metadata = session
.sftp()
.stat(link.path())
.metadata(link.path())
.await
.expect("Failed to stat symlink");
.expect("Failed to get metadata for symlink");
// Verify that file stat makes sense
assert!(metadata.is_dir(), "Invalid file stat returned");
assert!(metadata.ty.is_dir(), "Invalid file stat returned");
assert!(!metadata.ty.is_symlink(), "Invalid file stat returned");
// Verify that file metadata makes sense
assert!(metadata.is_dir(), "Invalid file metadata returned");
assert!(metadata.ty.is_dir(), "Invalid file metadata returned");
assert!(!metadata.ty.is_symlink(), "Invalid file metadata returned");
}
#[rstest]
#[smol_potat::test]
#[cfg_attr(not(any(target_os = "macos", target_os = "linux")), ignore)]
async fn stat_should_fail_if_path_missing(#[future] session: Session) {
async fn metadata_should_fail_if_path_missing(#[future] session: Session) {
let session: Session = session.await;
let temp = TempDir::new().unwrap();
let result = session.sftp().stat(temp.child("missing").path()).await;
assert!(result.is_err(), "Stat unexpectedly succeeded: {:?}", result);
}
#[rstest]
#[smol_potat::test]
#[cfg_attr(not(any(target_os = "macos", target_os = "linux")), ignore)]
async fn lstat_should_return_metadata_about_a_file(#[future] session: Session) {
let session: Session = session.await;
let temp = TempDir::new().unwrap();
let file = temp.child("file");
file.touch().unwrap();
let lstat = session
.sftp()
.lstat(file.path())
.await
.expect("Failed to lstat file");
// Verify that file lstat makes sense
assert!(lstat.is_file(), "Invalid file lstat returned");
}
#[rstest]
#[smol_potat::test]
#[cfg_attr(not(any(target_os = "macos", target_os = "linux")), ignore)]
async fn lstat_should_return_metadata_about_a_directory(#[future] session: Session) {
let session: Session = session.await;
let temp = TempDir::new().unwrap();
let dir = temp.child("dir");
dir.create_dir_all().unwrap();
let lstat = session
.sftp()
.lstat(dir.path())
.await
.expect("Failed to lstat dir");
// Verify that file lstat makes sense
assert!(lstat.is_dir(), "Invalid file lstat returned");
}
#[rstest]
#[smol_potat::test]
#[cfg_attr(not(any(target_os = "macos", target_os = "linux")), ignore)]
async fn lstat_should_return_metadata_about_symlink_pointing_to_a_file(#[future] session: Session) {
let session: Session = session.await;
let temp = TempDir::new().unwrap();
let file = temp.child("file");
file.touch().unwrap();
let link = temp.child("link");
link.symlink_to_file(file.path()).unwrap();
let metadata = session
.sftp()
.lstat(link.path())
.await
.expect("Failed to lstat symlink");
// Verify that file lstat makes sense
assert!(!metadata.is_file(), "Invalid file lstat returned");
assert!(!metadata.ty.is_file(), "Invalid file lstat returned");
assert!(metadata.ty.is_symlink(), "Invalid file lstat returned");
}
#[rstest]
#[smol_potat::test]
#[cfg_attr(not(any(target_os = "macos", target_os = "linux")), ignore)]
async fn lstat_should_return_metadata_about_symlink_pointing_to_a_directory(
#[future] session: Session,
) {
let session: Session = session.await;
let temp = TempDir::new().unwrap();
let dir = temp.child("dir");
dir.create_dir_all().unwrap();
let link = temp.child("link");
link.symlink_to_dir(dir.path()).unwrap();
let metadata = session
.sftp()
.lstat(link.path())
.await
.expect("Failed to lstat symlink");
// Verify that file lstat makes sense
assert!(!metadata.is_dir(), "Invalid file lstat returned");
assert!(!metadata.ty.is_dir(), "Invalid file lstat returned");
assert!(metadata.ty.is_symlink(), "Invalid file lstat returned");
}
#[rstest]
#[smol_potat::test]
#[cfg_attr(not(any(target_os = "macos", target_os = "linux")), ignore)]
async fn lstat_should_fail_if_path_missing(#[future] session: Session) {
let session: Session = session.await;
let temp = TempDir::new().unwrap();
let result = session.sftp().lstat(temp.child("missing").path()).await;
let result = session.sftp().metadata(temp.child("missing").path()).await;
assert!(
result.is_err(),
"lstat unexpectedly succeeded: {:?}",
"Metadata unexpectedly succeeded: {:?}",
result
);
}
#[rstest]
#[smol_potat::test]
#[cfg_attr(not(any(target_os = "macos", target_os = "linux")), ignore)]
async fn symlink_metadata_should_return_metadata_about_a_file(#[future] session: Session) {
let session: Session = session.await;
let temp = TempDir::new().unwrap();
let file = temp.child("file");
file.touch().unwrap();
let symlink_metadata = session
.sftp()
.symlink_metadata(file.path())
.await
.expect("Failed to get metadata for file");
// Verify that file metadata makes sense
assert!(symlink_metadata.is_file(), "Invalid file metadata returned");
}
#[rstest]
#[smol_potat::test]
#[cfg_attr(not(any(target_os = "macos", target_os = "linux")), ignore)]
async fn symlink_metadata_should_return_metadata_about_a_directory(#[future] session: Session) {
let session: Session = session.await;
let temp = TempDir::new().unwrap();
let dir = temp.child("dir");
dir.create_dir_all().unwrap();
let symlink_metadata = session
.sftp()
.symlink_metadata(dir.path())
.await
.expect("Failed to metadata for dir");
// Verify that file metadata makes sense
assert!(symlink_metadata.is_dir(), "Invalid file metadata returned");
}
#[rstest]
#[smol_potat::test]
#[cfg_attr(not(any(target_os = "macos", target_os = "linux")), ignore)]
async fn symlink_metadata_should_return_metadata_about_symlink_pointing_to_a_file(
#[future] session: Session,
) {
let session: Session = session.await;
let temp = TempDir::new().unwrap();
let file = temp.child("file");
file.touch().unwrap();
let link = temp.child("link");
link.symlink_to_file(file.path()).unwrap();
let metadata = session
.sftp()
.symlink_metadata(link.path())
.await
.expect("Failed to get metadata for symlink");
// Verify that file metadata makes sense
assert!(!metadata.is_file(), "Invalid file metadata returned");
assert!(!metadata.ty.is_file(), "Invalid file metadata returned");
assert!(metadata.ty.is_symlink(), "Invalid file metadata returned");
}
#[rstest]
#[smol_potat::test]
#[cfg_attr(not(any(target_os = "macos", target_os = "linux")), ignore)]
async fn symlink_metadata_should_return_metadata_about_symlink_pointing_to_a_directory(
#[future] session: Session,
) {
let session: Session = session.await;
let temp = TempDir::new().unwrap();
let dir = temp.child("dir");
dir.create_dir_all().unwrap();
let link = temp.child("link");
link.symlink_to_dir(dir.path()).unwrap();
let metadata = session
.sftp()
.symlink_metadata(link.path())
.await
.expect("Failed to get metadata for symlink");
// Verify that file metadata makes sense
assert!(!metadata.is_dir(), "Invalid file metadata returned");
assert!(!metadata.ty.is_dir(), "Invalid file metadata returned");
assert!(metadata.ty.is_symlink(), "Invalid file metadata returned");
}
#[rstest]
#[smol_potat::test]
#[cfg_attr(not(any(target_os = "macos", target_os = "linux")), ignore)]
async fn symlink_metadata_should_fail_if_path_missing(#[future] session: Session) {
let session: Session = session.await;
let temp = TempDir::new().unwrap();
let result = session
.sftp()
.symlink_metadata(temp.child("missing").path())
.await;
assert!(
result.is_err(),
"symlink_metadata unexpectedly succeeded: {:?}",
result
);
}
@ -467,7 +481,7 @@ async fn symlink_should_succeed_even_if_path_missing(#[future] session: Session)
#[rstest]
#[smol_potat::test]
#[cfg_attr(not(any(target_os = "macos", target_os = "linux")), ignore)]
async fn readlink_should_return_the_target_of_the_symlink(#[future] session: Session) {
async fn read_link_should_return_the_target_of_the_symlink(#[future] session: Session) {
let session: Session = session.await;
let temp = TempDir::new().unwrap();
@ -480,7 +494,7 @@ async fn readlink_should_return_the_target_of_the_symlink(#[future] session: Ses
let path = session
.sftp()
.readlink(link.path())
.read_link(link.path())
.await
.expect("Failed to read symlink");
assert_eq!(path, dir.path());
@ -493,7 +507,7 @@ async fn readlink_should_return_the_target_of_the_symlink(#[future] session: Ses
let path = session
.sftp()
.readlink(link.path())
.read_link(link.path())
.await
.expect("Failed to read symlink");
assert_eq!(path, file.path());
@ -502,13 +516,13 @@ async fn readlink_should_return_the_target_of_the_symlink(#[future] session: Ses
#[rstest]
#[smol_potat::test]
#[cfg_attr(not(any(target_os = "macos", target_os = "linux")), ignore)]
async fn readlink_should_fail_if_path_is_not_a_symlink(#[future] session: Session) {
async fn read_link_should_fail_if_path_is_not_a_symlink(#[future] session: Session) {
let session: Session = session.await;
let temp = TempDir::new().unwrap();
// Test missing path
let result = session.sftp().readlink(temp.child("missing").path()).await;
let result = session.sftp().read_link(temp.child("missing").path()).await;
assert!(
result.is_err(),
"Unexpectedly read link for missing path: {:?}",
@ -518,7 +532,7 @@ async fn readlink_should_fail_if_path_is_not_a_symlink(#[future] session: Sessio
// Test a directory
let dir = temp.child("dir");
dir.create_dir_all().unwrap();
let result = session.sftp().readlink(dir.path()).await;
let result = session.sftp().read_link(dir.path()).await;
assert!(
result.is_err(),
"Unexpectedly read link for directory: {:?}",
@ -528,7 +542,7 @@ async fn readlink_should_fail_if_path_is_not_a_symlink(#[future] session: Sessio
// Test a file
let file = temp.child("file");
file.touch().unwrap();
let result = session.sftp().readlink(file.path()).await;
let result = session.sftp().read_link(file.path()).await;
assert!(
result.is_err(),
"Unexpectedly read link for file: {:?}",
@ -539,7 +553,7 @@ async fn readlink_should_fail_if_path_is_not_a_symlink(#[future] session: Sessio
#[rstest]
#[smol_potat::test]
#[cfg_attr(not(any(target_os = "macos", target_os = "linux")), ignore)]
async fn realpath_should_resolve_absolute_path_for_relative_path(#[future] session: Session) {
async fn canonicalize_should_resolve_absolute_path_for_relative_path(#[future] session: Session) {
let session: Session = session.await;
// For resolving parts of a path, all components must exist
@ -549,19 +563,23 @@ async fn realpath_should_resolve_absolute_path_for_relative_path(#[future] sessi
let rel = temp.child(".").child("hello").child("..").child("world");
// NOTE: Because realpath can still resolve symlinks within a missing path, there
// NOTE: Because sftp realpath can still resolve symlinks within a missing path, there
// is no guarantee that the resulting path matches the missing path. In fact,
// on mac the /tmp dir is a symlink to /private/tmp; so, we cannot successfully
// check the accuracy of the path itself, meaning that we can only validate
// that the operation was okay.
let result = session.sftp().realpath(rel.path()).await;
assert!(result.is_ok(), "Realpath unexpectedly failed: {:?}", result);
let result = session.sftp().canonicalize(rel.path()).await;
assert!(
result.is_ok(),
"Canonicalize unexpectedly failed: {:?}",
result
);
}
#[rstest]
#[smol_potat::test]
#[cfg_attr(not(any(target_os = "macos", target_os = "linux")), ignore)]
async fn realpath_should_either_return_resolved_path_or_error_if_missing(
async fn canonicalize_should_either_return_resolved_path_or_error_if_missing(
#[future] session: Session,
) {
let session: Session = session.await;
@ -569,7 +587,7 @@ async fn realpath_should_either_return_resolved_path_or_error_if_missing(
let temp = TempDir::new().unwrap();
let missing = temp.child("missing");
// NOTE: Because realpath can still resolve symlinks within a missing path, there
// NOTE: Because sftp realpath can still resolve symlinks within a missing path, there
// is no guarantee that the resulting path matches the missing path. In fact,
// on mac the /tmp dir is a symlink to /private/tmp; so, we cannot successfully
// check the accuracy of the path itself, meaning that we can only validate
@ -578,25 +596,25 @@ async fn realpath_should_either_return_resolved_path_or_error_if_missing(
// Additionally, this has divergent behavior. On some platforms, this returns
// the path as is whereas on others this returns a missing path error. We
// have to support both checks.
let result = session.sftp().realpath(missing.path()).await;
let result = session.sftp().canonicalize(missing.path()).await;
match result {
Ok(_) => {}
Err(SftpChannelError::Sftp(SftpError::NoSuchFile)) => {}
x => panic!("Unexpected result from realpath: {:?}", x),
x => panic!("Unexpected result from canonicalize: {:?}", x),
}
}
#[rstest]
#[smol_potat::test]
#[cfg_attr(not(any(target_os = "macos", target_os = "linux")), ignore)]
async fn realpath_should_fail_if_resolving_missing_path_with_dots(#[future] session: Session) {
async fn canonicalize_should_fail_if_resolving_missing_path_with_dots(#[future] session: Session) {
let session: Session = session.await;
let temp = TempDir::new().unwrap();
let missing = temp.child(".").child("hello").child("..").child("world");
let result = session.sftp().realpath(missing.path()).await;
assert!(result.is_err(), "Realpath unexpectedly succeeded");
let result = session.sftp().canonicalize(missing.path()).await;
assert!(result.is_err(), "Canonicalize unexpectedly succeeded");
}
#[rstest]
@ -678,7 +696,7 @@ async fn rename_should_fail_if_source_path_missing(#[future] session: Session) {
#[rstest]
#[smol_potat::test]
#[cfg_attr(not(any(target_os = "macos", target_os = "linux")), ignore)]
async fn unlink_should_remove_file(#[future] session: Session) {
async fn remove_file_should_remove_file(#[future] session: Session) {
let session: Session = session.await;
let temp = TempDir::new().unwrap();
@ -687,9 +705,9 @@ async fn unlink_should_remove_file(#[future] session: Session) {
session
.sftp()
.unlink(file.path())
.remove_file(file.path())
.await
.expect("Failed to unlink file");
.expect("Failed to remove file");
file.assert(predicate::path::missing());
}
@ -697,7 +715,7 @@ async fn unlink_should_remove_file(#[future] session: Session) {
#[rstest]
#[smol_potat::test]
#[cfg_attr(not(any(target_os = "macos", target_os = "linux")), ignore)]
async fn unlink_should_remove_symlink_to_file(#[future] session: Session) {
async fn remove_file_should_remove_symlink_to_file(#[future] session: Session) {
let session: Session = session.await;
let temp = TempDir::new().unwrap();
@ -708,9 +726,9 @@ async fn unlink_should_remove_symlink_to_file(#[future] session: Session) {
session
.sftp()
.unlink(link.path())
.remove_file(link.path())
.await
.expect("Failed to unlink symlink");
.expect("Failed to remove symlink");
// Verify link removed but file still exists
link.assert(predicate::path::missing());
@ -720,7 +738,7 @@ async fn unlink_should_remove_symlink_to_file(#[future] session: Session) {
#[rstest]
#[smol_potat::test]
#[cfg_attr(not(any(target_os = "macos", target_os = "linux")), ignore)]
async fn unlink_should_remove_symlink_to_directory(#[future] session: Session) {
async fn remove_file_should_remove_symlink_to_directory(#[future] session: Session) {
let session: Session = session.await;
let temp = TempDir::new().unwrap();
@ -731,9 +749,9 @@ async fn unlink_should_remove_symlink_to_directory(#[future] session: Session) {
session
.sftp()
.unlink(link.path())
.remove_file(link.path())
.await
.expect("Failed to unlink symlink");
.expect("Failed to remove symlink");
// Verify link removed but directory still exists
link.assert(predicate::path::missing());
@ -743,17 +761,17 @@ async fn unlink_should_remove_symlink_to_directory(#[future] session: Session) {
#[rstest]
#[smol_potat::test]
#[cfg_attr(not(any(target_os = "macos", target_os = "linux")), ignore)]
async fn unlink_should_fail_if_path_to_directory(#[future] session: Session) {
async fn remove_file_should_fail_if_path_to_directory(#[future] session: Session) {
let session: Session = session.await;
let temp = TempDir::new().unwrap();
let dir = temp.child("dir");
dir.create_dir_all().unwrap();
let result = session.sftp().unlink(dir.path()).await;
let result = session.sftp().remove_file(dir.path()).await;
assert!(
result.is_err(),
"Unexpectedly unlinked directory: {:?}",
"Unexpectedly removed directory: {:?}",
result
);
@ -764,15 +782,18 @@ async fn unlink_should_fail_if_path_to_directory(#[future] session: Session) {
#[rstest]
#[smol_potat::test]
#[cfg_attr(not(any(target_os = "macos", target_os = "linux")), ignore)]
async fn unlink_should_fail_if_path_missing(#[future] session: Session) {
async fn remove_file_should_fail_if_path_missing(#[future] session: Session) {
let session: Session = session.await;
let temp = TempDir::new().unwrap();
let result = session.sftp().unlink(temp.child("missing").path()).await;
let result = session
.sftp()
.remove_file(temp.child("missing").path())
.await;
assert!(
result.is_err(),
"Unexpectedly unlinked missing path: {:?}",
"Unexpectedly removed missing path: {:?}",
result
);
}

View File

@ -8,7 +8,7 @@ use wezterm_ssh::Session;
#[rstest]
#[smol_potat::test]
#[cfg_attr(not(any(target_os = "macos", target_os = "linux")), ignore)]
async fn stat_should_retrieve_file_stat(#[future] session: Session) {
async fn metadata_should_retrieve_file_stat(#[future] session: Session) {
let session: Session = session.await;
let temp = TempDir::new().unwrap();
@ -21,16 +21,19 @@ async fn stat_should_retrieve_file_stat(#[future] session: Session) {
.await
.expect("Failed to open remote file");
let stat = remote_file.stat().await.expect("Failed to read file stat");
let metadata = remote_file
.metadata()
.await
.expect("Failed to read file metadata");
// Verify that file stat makes sense
assert!(stat.is_file(), "Invalid file stat returned");
assert!(metadata.is_file(), "Invalid file metadata returned");
}
#[rstest]
#[smol_potat::test]
#[cfg_attr(not(any(target_os = "macos", target_os = "linux")), ignore)]
async fn readdir_should_retrieve_next_dir_entry(#[future] session: Session) {
async fn read_dir_should_retrieve_next_dir_entry(#[future] session: Session) {
let session: Session = session.await;
let temp = TempDir::new().unwrap();
@ -43,13 +46,13 @@ async fn readdir_should_retrieve_next_dir_entry(#[future] session: Session) {
let remote_dir = session
.sftp()
.opendir(temp.path())
.open_dir(temp.path())
.await
.expect("Failed to open remote directory");
// Collect all of the directory contents (. and .. are included)
let mut contents = Vec::new();
while let Ok((path, metadata)) = remote_dir.readdir().await {
while let Ok((path, metadata)) = remote_dir.read_dir().await {
let ft = metadata.ty;
contents.push((
path,