use super::{Metadata, SessionRequest, SessionSender, SftpChannelResult, SftpRequest};
use camino::Utf8PathBuf;
use smol::channel::{bounded, Sender};
use std::fmt;
pub(crate) type DirId = usize;
pub struct Dir {
pub(crate) dir_id: DirId,
tx: Option<SessionSender>,
}
impl fmt::Debug for Dir {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Dir").field("dir_id", &self.dir_id).finish()
}
}
#[derive(Debug)]
pub(crate) enum DirRequest {
Close(DirId, Sender<SftpChannelResult<()>>),
ReadDir(DirId, Sender<SftpChannelResult<(Utf8PathBuf, Metadata)>>),
}
impl Drop for Dir {
fn drop(&mut self) {
if let Some(tx) = self.tx.take() {
let (reply, _) = bounded(1);
let _ = tx.try_send(SessionRequest::Sftp(SftpRequest::Dir(DirRequest::Close(
self.dir_id,
reply,
))));
}
}
}
impl Dir {
pub(crate) fn new(dir_id: DirId) -> Self {
Self { dir_id, tx: None }
}
pub(crate) fn initialize_sender(&mut self, sender: SessionSender) {
self.tx.replace(sender);
}
pub async fn read_dir(&self) -> anyhow::Result<(Utf8PathBuf, Metadata)> {
let (reply, rx) = bounded(1);
self.tx
.as_ref()
.unwrap()
.send(SessionRequest::Sftp(SftpRequest::Dir(DirRequest::ReadDir(
self.dir_id,
reply,
))))
.await?;
let result = rx.recv().await??;
Ok(result)
}
}