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, Clone)]
24pub struct Connector {
25 inner: Arc<dyn Connectable>,
26}
27
28impl CapabilityBound for Connector {
29 fn debug_typename() -> &'static str {
30 "Connector"
31 }
32}
33
34impl Connector {
35 pub fn new() -> (Receiver, Self) {
36 let (sender, receiver) = mpsc::unbounded();
37 let receiver = Receiver::new(receiver);
38 let this = Self::new_sendable(sender);
39 (receiver, this)
40 }
41
42 pub fn new_sendable(connector: impl Connectable + 'static) -> Self {
43 Self { inner: Arc::new(connector) }
44 }
45
46 pub fn send(&self, channel: fidl::Channel) -> Result<(), ()> {
47 self.inner.send(channel)
48 }
49}
50
51impl Connectable for Connector {
52 fn send(&self, channel: fidl::Channel) -> Result<(), ()> {
53 self.send(channel)
54 }
55}
56
57#[cfg(test)]
58mod tests {
59 use super::*;
60 use fidl::handle::{Channel, HandleBased, Rights};
61 use fidl_fuchsia_component_sandbox as fsandbox;
62
63 #[fuchsia::test]
68 async fn fidl_clone() {
69 let (receiver, sender) = Connector::new();
70
71 let (ch1, _ch2) = Channel::create();
73 sender.send(ch1).unwrap();
74
75 let connector: fsandbox::Connector = sender.into();
77
78 let token_clone = fsandbox::Connector {
80 token: connector.token.duplicate_handle(Rights::SAME_RIGHTS).unwrap(),
81 };
82 let connector_clone = match crate::Capability::try_from(fsandbox::Capability::Connector(
83 token_clone,
84 ))
85 .unwrap()
86 {
87 crate::Capability::Connector(connector) => connector,
88 capability @ _ => panic!("wrong type {capability:?}"),
89 };
90
91 let (ch1, _ch2) = Channel::create();
93 connector_clone.send(ch1).unwrap();
94
95 for _ in 0..2 {
97 let _ch = receiver.receive().await.unwrap();
98 }
99 }
100}