runtime_capabilities/
connector.rs1use crate::{CapabilityBound, Receiver};
6use futures::channel::mpsc;
7use std::fmt::Debug;
8use std::sync::Arc;
9
10pub trait Connectable: Send + Sync + Debug {
13 fn send(&self, channel: fidl::Channel) -> Result<(), ()>;
14}
15
16impl Connectable for mpsc::UnboundedSender<fidl::Channel> {
17 fn send(&self, channel: fidl::Channel) -> Result<(), ()> {
18 self.unbounded_send(channel).map_err(|_| ())
19 }
20}
21
22#[derive(Debug)]
24pub struct Connector {
25 inner: Box<dyn Connectable>,
26}
27
28impl CapabilityBound for Connector {
29 fn debug_typename() -> &'static str {
30 "Connector"
31 }
32
33 #[cfg(target_os = "fuchsia")]
34 fn try_into_directory_entry(
35 self: Arc<Self>,
36 _scope: vfs::execution_scope::ExecutionScope,
37 _token: Arc<crate::WeakInstanceToken>,
38 ) -> Result<Arc<dyn vfs::directory::entry::DirectoryEntry>, crate::ConversionError> {
39 Ok(vfs::service::endpoint(move |_scope, server_end| {
40 let _ = self.send(server_end.into_zx_channel().into());
41 }))
42 }
43}
44
45impl Connector {
46 pub fn new() -> (Receiver, Arc<Self>) {
47 let (sender, receiver) = mpsc::unbounded();
48 let receiver = Receiver::new(receiver);
49 let this = Self::new_sendable(sender);
50 (receiver, this)
51 }
52
53 pub fn new_sendable(connector: impl Connectable + 'static) -> Arc<Self> {
54 Arc::new(Self { inner: Box::new(connector) })
55 }
56
57 pub fn send(&self, channel: fidl::Channel) -> Result<(), ()> {
58 self.inner.send(channel)
59 }
60}
61
62impl Connectable for Connector {
63 fn send(&self, channel: fidl::Channel) -> Result<(), ()> {
64 self.send(channel)
65 }
66}
67
68#[cfg(test)]
69mod tests {
70 use super::*;
71 use crate::Capability;
72 use fidl::handle::{Channel, Rights};
73 use fidl_fuchsia_component_sandbox as fsandbox;
74
75 #[fuchsia::test]
80 async fn fidl_clone() {
81 let (receiver, sender) = Connector::new();
82
83 let (ch1, _ch2) = Channel::create();
85 sender.send(ch1).unwrap();
86
87 let connector: fsandbox::Connector = sender.to_fsandbox();
89
90 let token_clone = fsandbox::Connector {
92 token: connector.token.duplicate_handle(Rights::SAME_RIGHTS).unwrap(),
93 };
94 let connector_clone =
95 match Capability::try_from(fsandbox::Capability::Connector(token_clone)).unwrap() {
96 Capability::Connector(connector) => connector,
97 capability @ _ => panic!("wrong type {capability:?}"),
98 };
99
100 let (ch1, _ch2) = Channel::create();
102 connector_clone.send(ch1).unwrap();
103
104 for _ in 0..2 {
106 let _ch = receiver.receive().await.unwrap();
107 }
108 }
109}