1use crate::{CapabilityBound, Receiver};
6use fidl_fuchsia_component_sandbox as fsandbox;
7use futures::channel::mpsc;
8use std::fmt::Debug;
9use std::sync::Arc;
10
11#[derive(Debug)]
12pub struct Message {
13 pub channel: fidl::Channel,
14}
15
16impl From<fsandbox::ProtocolPayload> for Message {
17 fn from(payload: fsandbox::ProtocolPayload) -> Self {
18 Message { channel: payload.channel }
19 }
20}
21
22pub trait Connectable: Send + Sync + Debug {
25 fn send(&self, message: Message) -> Result<(), ()>;
26}
27
28impl Connectable for mpsc::UnboundedSender<crate::Message> {
29 fn send(&self, message: Message) -> Result<(), ()> {
30 self.unbounded_send(message).map_err(|_| ())
31 }
32}
33
34#[derive(Debug, Clone)]
36pub struct Connector {
37 inner: Arc<dyn Connectable>,
38}
39
40impl CapabilityBound for Connector {
41 fn debug_typename() -> &'static str {
42 "Connector"
43 }
44}
45
46impl Connector {
47 pub fn new() -> (Receiver, Self) {
48 let (sender, receiver) = mpsc::unbounded();
49 let receiver = Receiver::new(receiver);
50 let this = Self::new_sendable(sender);
51 (receiver, this)
52 }
53
54 pub fn new_sendable(connector: impl Connectable + 'static) -> Self {
55 Self { inner: Arc::new(connector) }
56 }
57
58 pub fn send(&self, msg: Message) -> Result<(), ()> {
59 self.inner.send(msg)
60 }
61}
62
63impl Connectable for Connector {
64 fn send(&self, message: Message) -> Result<(), ()> {
65 self.send(message)
66 }
67}
68
69#[cfg(test)]
70mod tests {
71 use super::*;
72 use fidl::handle::{Channel, HandleBased, Rights};
73
74 #[fuchsia::test]
79 async fn fidl_clone() {
80 let (receiver, sender) = Connector::new();
81
82 let (ch1, _ch2) = Channel::create();
84 sender.send_channel(ch1).unwrap();
85
86 let connector: fsandbox::Connector = sender.into();
88
89 let token_clone = fsandbox::Connector {
91 token: connector.token.duplicate_handle(Rights::SAME_RIGHTS).unwrap(),
92 };
93 let connector_clone = match crate::Capability::try_from(fsandbox::Capability::Connector(
94 token_clone,
95 ))
96 .unwrap()
97 {
98 crate::Capability::Connector(connector) => connector,
99 capability @ _ => panic!("wrong type {capability:?}"),
100 };
101
102 let (ch1, _ch2) = Channel::create();
104 connector_clone.send_channel(ch1).unwrap();
105
106 for _ in 0..2 {
108 let _ch = receiver.receive().await.unwrap();
109 }
110 }
111}