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(
21 self: Arc<Self>,
22 scope: ExecutionScope,
23 flags: fio::OpenFlags,
24 path: Path,
25 server_end: ServerEnd<fio::NodeMarker>,
26 );
27
28 fn open3(
29 self: Arc<Self>,
30 scope: ExecutionScope,
31 path: Path,
32 flags: fio::Flags,
33 object_request: ObjectRequestRef<'_>,
34 ) -> Result<(), Status>;
35
36 fn lazy(&self, _path: &Path) -> bool {
41 false
42 }
43}
44
45pub fn remote_dir(dir: fio::DirectoryProxy) -> Arc<impl DirectoryEntry + RemoteLike> {
48 Arc::new(RemoteDir { dir })
49}
50
51struct RemoteDir {
54 dir: fio::DirectoryProxy,
55}
56
57impl GetRemoteDir for RemoteDir {
58 fn get_remote_dir(&self) -> Result<fio::DirectoryProxy, Status> {
59 Ok(Clone::clone(&self.dir))
60 }
61}
62
63pub trait GetRemoteDir {
66 fn get_remote_dir(&self) -> Result<fio::DirectoryProxy, Status>;
67}
68
69impl<T: GetRemoteDir + Send + Sync + 'static> GetEntryInfo for T {
70 fn entry_info(&self) -> EntryInfo {
71 EntryInfo::new(fio::INO_UNKNOWN, fio::DirentType::Directory)
72 }
73}
74
75impl<T: GetRemoteDir + Send + Sync + 'static> DirectoryEntry for T {
76 fn open_entry(self: Arc<Self>, request: OpenRequest<'_>) -> Result<(), Status> {
77 request.open_remote(self)
78 }
79}
80
81impl<T: GetRemoteDir> RemoteLike for T {
82 fn open(
83 self: Arc<Self>,
84 _scope: ExecutionScope,
85 flags: fio::OpenFlags,
86 path: Path,
87 server_end: ServerEnd<fio::NodeMarker>,
88 ) {
89 flags.to_object_request(server_end).handle(|object_request| {
90 #[cfg(fuchsia_api_level_at_least = "NEXT")]
91 let _ = self.get_remote_dir()?.deprecated_open(
92 flags,
93 fio::ModeType::empty(),
94 path.as_ref(),
95 object_request.take().into_server_end(),
96 );
97 #[cfg(not(fuchsia_api_level_at_least = "NEXT"))]
98 let _ = self.get_remote_dir()?.open(
99 flags,
100 fio::ModeType::empty(),
101 path.as_ref(),
102 object_request.take().into_server_end(),
103 );
104 Ok(())
105 });
106 }
107
108 fn open3(
109 self: Arc<Self>,
110 _scope: ExecutionScope,
111 path: Path,
112 flags: fio::Flags,
113 object_request: ObjectRequestRef<'_>,
114 ) -> Result<(), Status> {
115 #[cfg(fuchsia_api_level_at_least = "NEXT")]
118 let _ = self.get_remote_dir()?.open(
119 path.as_ref(),
120 flags,
121 &object_request.options(),
122 object_request.take().into_channel(),
123 );
124 #[cfg(not(fuchsia_api_level_at_least = "NEXT"))]
125 let _ = self.get_remote_dir()?.open3(
126 path.as_ref(),
127 flags,
128 &object_request.options(),
129 object_request.take().into_channel(),
130 );
131 Ok(())
132 }
133}