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 #[cfg(fuchsia_api_level_at_least = "NEXT")]
94 let _ = self.get_remote_dir()?.deprecated_open(
95 flags,
96 fio::ModeType::empty(),
97 path.as_ref(),
98 object_request.take().into_server_end(),
99 );
100 #[cfg(not(fuchsia_api_level_at_least = "NEXT"))]
101 let _ = self.get_remote_dir()?.open(
102 flags,
103 fio::ModeType::empty(),
104 path.as_ref(),
105 object_request.take().into_server_end(),
106 );
107 Ok(())
108 });
109 }
110
111 fn open(
112 self: Arc<Self>,
113 _scope: ExecutionScope,
114 path: Path,
115 flags: fio::Flags,
116 object_request: ObjectRequestRef<'_>,
117 ) -> Result<(), Status> {
118 #[cfg(fuchsia_api_level_at_least = "NEXT")]
121 let _ = self.get_remote_dir()?.open(
122 path.as_ref(),
123 flags,
124 &object_request.options(),
125 object_request.take().into_channel(),
126 );
127 #[cfg(not(fuchsia_api_level_at_least = "NEXT"))]
128 let _ = self.get_remote_dir()?.open3(
129 path.as_ref(),
130 flags,
131 &object_request.options(),
132 object_request.take().into_channel(),
133 );
134 Ok(())
135 }
136}