use std::path::Path;
use crate::logging::trace;
use crate::fs::helpers::os_str_to_str;
use crate::rpc::res::{ReadDirItem, Response};
use crate::transport::Transport;
use crate::transport::serial::rpc::CommandIndex;
use crate::{
error::{Error, Result},
proto::{self, storage::ListRequest},
rpc::req::Request,
transport::TransportRaw,
};
pub trait FsReadDir {
fn fs_read_dir(
&mut self,
path: impl AsRef<Path>,
include_md5: bool,
) -> Result<impl Iterator<Item = ReadDirItem>>;
}
impl<T> FsReadDir for T
where
T: TransportRaw<proto::Main, proto::Main, Err = Error> + CommandIndex + std::fmt::Debug,
{
fn fs_read_dir(
&mut self,
path: impl AsRef<Path>,
include_md5: bool,
) -> Result<impl Iterator<Item = ReadDirItem>> {
let path = os_str_to_str(path.as_ref().as_os_str())?.to_string();
let mut items = Vec::new();
trace!("init readdir chain");
self.send(Request::StorageList(ListRequest {
path,
include_md5,
filter_max_size: 0,
}))?;
loop {
let response = self.receive_raw()?;
trace!("readdir chunk");
let has_next = response.has_next;
let chunk: Vec<ReadDirItem> = Response::try_from(response)?.try_into()?;
items.extend(chunk);
if !has_next {
break;
}
}
Ok(items.into_iter())
}
}