1#[cfg(test)]
8mod tests;
9
10use crate::directory::entry::{DirectoryEntry, EntryInfo, GetEntryInfo, OpenRequest};
11use crate::execution_scope::ExecutionScope;
12use crate::path::Path;
13use crate::{ObjectRequestRef, ToObjectRequest as _};
14use fidl::endpoints::ServerEnd;
15use fidl_fuchsia_io as fio;
16use std::sync::Arc;
17use zx_status::Status;
18
19pub trait RemoteLike {
20 fn open(
22 self: Arc<Self>,
23 scope: ExecutionScope,
24 path: Path,
25 flags: fio::Flags,
26 object_request: ObjectRequestRef<'_>,
27 ) -> Result<(), Status>;
28
29 fn lazy(&self, _path: &Path) -> bool {
34 false
35 }
36
37 fn deprecated_open(
40 self: Arc<Self>,
41 _scope: ExecutionScope,
42 flags: fio::OpenFlags,
43 _path: Path,
44 server_end: ServerEnd<fio::NodeMarker>,
45 ) {
46 flags.to_object_request(server_end.into_channel()).shutdown(Status::NOT_SUPPORTED);
47 }
48}
49
50pub fn remote_dir(dir: fio::DirectoryProxy) -> Arc<impl DirectoryEntry + RemoteLike> {
52 Arc::new(RemoteDir { dir })
53}
54
55struct RemoteDir {
57 dir: fio::DirectoryProxy,
58}
59
60impl GetRemoteDir for RemoteDir {
61 fn get_remote_dir(&self) -> Result<fio::DirectoryProxy, Status> {
62 Ok(Clone::clone(&self.dir))
63 }
64}
65
66pub trait GetRemoteDir {
69 fn get_remote_dir(&self) -> Result<fio::DirectoryProxy, Status>;
70}
71
72impl<T: GetRemoteDir + Send + Sync + 'static> GetEntryInfo for T {
73 fn entry_info(&self) -> EntryInfo {
74 EntryInfo::new(fio::INO_UNKNOWN, fio::DirentType::Directory)
75 }
76}
77
78impl<T: GetRemoteDir + Send + Sync + 'static> DirectoryEntry for T {
79 fn open_entry(self: Arc<Self>, request: OpenRequest<'_>) -> Result<(), Status> {
80 request.open_remote(self)
81 }
82}
83
84impl<T: GetRemoteDir> RemoteLike for T {
85 fn deprecated_open(
86 self: Arc<Self>,
87 _scope: ExecutionScope,
88 flags: fio::OpenFlags,
89 path: Path,
90 server_end: ServerEnd<fio::NodeMarker>,
91 ) {
92 flags.to_object_request(server_end).handle(|object_request| {
93 let _ = self.get_remote_dir()?.deprecated_open(
94 flags,
95 fio::ModeType::empty(),
96 path.as_ref(),
97 object_request.take().into_server_end(),
98 );
99 Ok(())
100 });
101 }
102
103 fn open(
104 self: Arc<Self>,
105 _scope: ExecutionScope,
106 path: Path,
107 flags: fio::Flags,
108 object_request: ObjectRequestRef<'_>,
109 ) -> Result<(), Status> {
110 let _ = self.get_remote_dir()?.open(
113 path.as_ref(),
114 flags,
115 &object_request.options(),
116 object_request.take().into_channel(),
117 );
118 Ok(())
119 }
120}