#[cfg(test)]
mod tests;
use crate::directory::entry::{DirectoryEntry, EntryInfo, GetEntryInfo, OpenRequest};
use crate::execution_scope::ExecutionScope;
use crate::path::Path;
use crate::{ObjectRequestRef, ToObjectRequest as _};
use fidl::endpoints::ServerEnd;
use fidl_fuchsia_io as fio;
use std::sync::Arc;
use zx_status::Status;
pub trait RemoteLike {
fn open(
self: Arc<Self>,
scope: ExecutionScope,
flags: fio::OpenFlags,
path: Path,
server_end: ServerEnd<fio::NodeMarker>,
);
fn open3(
self: Arc<Self>,
_scope: ExecutionScope,
_path: Path,
_flags: fio::Flags,
_object_request: ObjectRequestRef<'_>,
) -> Result<(), Status> {
Err(Status::NOT_SUPPORTED)
}
fn lazy(&self, _path: &Path) -> bool {
false
}
}
pub fn remote_dir(dir: fio::DirectoryProxy) -> Arc<impl DirectoryEntry + RemoteLike> {
Arc::new(RemoteDir { dir })
}
struct RemoteDir {
dir: fio::DirectoryProxy,
}
impl GetRemoteDir for RemoteDir {
fn get_remote_dir(&self) -> Result<fio::DirectoryProxy, Status> {
Ok(Clone::clone(&self.dir))
}
}
pub trait GetRemoteDir {
fn get_remote_dir(&self) -> Result<fio::DirectoryProxy, Status>;
}
impl<T: GetRemoteDir + Send + Sync + 'static> GetEntryInfo for T {
fn entry_info(&self) -> EntryInfo {
EntryInfo::new(fio::INO_UNKNOWN, fio::DirentType::Directory)
}
}
impl<T: GetRemoteDir + Send + Sync + 'static> DirectoryEntry for T {
fn open_entry(self: Arc<Self>, request: OpenRequest<'_>) -> Result<(), Status> {
request.open_remote(self)
}
}
impl<T: GetRemoteDir> RemoteLike for T {
fn open(
self: Arc<Self>,
_scope: ExecutionScope,
flags: fio::OpenFlags,
path: Path,
server_end: ServerEnd<fio::NodeMarker>,
) {
flags.to_object_request(server_end).handle(|object_request| {
let _ = self.get_remote_dir()?.open(
flags,
fio::ModeType::empty(),
path.as_ref(),
object_request.take().into_server_end(),
);
Ok(())
});
}
fn open3(
self: Arc<Self>,
_scope: ExecutionScope,
path: Path,
flags: fio::Flags,
object_request: ObjectRequestRef<'_>,
) -> Result<(), Status> {
let _ = self.get_remote_dir()?.open3(
path.as_ref(),
flags,
&object_request.options(),
object_request.take().into_channel(),
);
Ok(())
}
}