1use crate::CapabilityBound;
6use fidl::handle::{self, HandleBased};
7
8#[derive(Debug)]
10pub struct Handle(handle::NullableHandle);
11
12impl Handle {
13 pub fn new(handle: handle::NullableHandle) -> Self {
15 Self(handle)
16 }
17}
18
19impl From<handle::NullableHandle> for Handle {
20 fn from(handle: handle::NullableHandle) -> Self {
21 Self(handle)
22 }
23}
24
25impl CapabilityBound for Handle {
26 fn debug_typename() -> &'static str {
27 "Handle"
28 }
29}
30
31impl Handle {
32 pub fn try_clone(&self) -> Result<Self, ()> {
33 Ok(Self(self.0.duplicate_handle(fidl::Rights::SAME_RIGHTS).map_err(|_| ())?))
34 }
35}
36
37impl From<Handle> for handle::NullableHandle {
38 fn from(value: Handle) -> Self {
39 value.0
40 }
41}
42
43#[cfg(target_os = "fuchsia")]
44#[cfg(test)]
45mod tests {
46 use super::*;
47 use crate::fidl::IntoFsandboxCapability;
48 use crate::{Capability, WeakInstanceToken};
49 use assert_matches::assert_matches;
50 use fidl::handle::{AsHandleRef, HandleBased};
51 use fidl_fuchsia_component_sandbox as fsandbox;
52
53 #[fuchsia::test]
55 async fn handle_into_fidl() {
56 let event = zx::Event::create();
57 let expected_koid = event.get_koid().unwrap();
58
59 let handle = Handle::from(event.into_handle());
60
61 let fidl_capability: fsandbox::Capability =
63 handle.into_fsandbox_capability(WeakInstanceToken::new_invalid());
64 assert_matches!(&fidl_capability, fsandbox::Capability::Handle(_));
65
66 let any: Capability = fidl_capability.try_into().unwrap();
67 let handle = assert_matches!(any, Capability::Handle(h) => h);
68
69 let handle: zx::NullableHandle = handle.into();
71
72 let got_koid = handle.get_koid().unwrap();
74 assert_eq!(got_koid, expected_koid);
75 }
76
77 #[fuchsia::test]
79 async fn try_clone() {
80 let event = zx::Event::create();
81 let expected_koid = event.get_koid().unwrap();
82
83 let handle = Handle::from(event.into_handle());
84 let handle = handle.try_clone().unwrap();
85 let handle: zx::NullableHandle = handle.into();
86
87 let got_koid = handle.get_koid().unwrap();
88 assert_eq!(got_koid, expected_koid);
89
90 let (ch, _) = zx::Channel::create();
91 let handle = Handle::from(ch.into_handle());
92 assert_matches!(handle.try_clone(), Err(()));
93 }
94}