1#[cfg(fuchsia_api_level_at_least = "HEAD")]
9pub use everything::*;
10
11#[cfg(fuchsia_api_level_less_than = "HEAD")]
12mod everything {
13 use fidl as _;
14 use fidl_fuchsia_component_runtime as _;
15 use fidl_fuchsia_io as _;
16 use fuchsia_component_client as _;
17 use futures as _;
18 use zx as _;
19
20 #[cfg(test)]
21 mod tests {
22 use assert_matches as _;
23 }
24}
25
26#[cfg(fuchsia_api_level_at_least = "HEAD")]
27mod everything {
28 use fidl::endpoints::{ServerEnd, create_proxy, create_request_stream};
29 use fidl_fuchsia_component_runtime as fruntime;
30 use fidl_fuchsia_io as fio;
31 use fuchsia_component_client::connect_to_protocol;
32 use futures::future::BoxFuture;
33 use futures::{Future, Stream, StreamExt};
34 use std::pin::{Pin, pin};
35 use std::task::{Context, Poll};
36
37 #[derive(Debug, PartialEq, Clone)]
39 pub enum DataValue {
40 Bytes(Vec<u8>),
41 String(String),
42 Int64(i64),
43 Uint64(u64),
44 }
45
46 impl From<Vec<u8>> for DataValue {
47 fn from(val: Vec<u8>) -> Self {
48 Self::Bytes(val)
49 }
50 }
51
52 impl From<String> for DataValue {
53 fn from(val: String) -> Self {
54 Self::String(val)
55 }
56 }
57
58 impl From<i64> for DataValue {
59 fn from(val: i64) -> Self {
60 Self::Int64(val)
61 }
62 }
63
64 impl From<u64> for DataValue {
65 fn from(val: u64) -> Self {
66 Self::Uint64(val)
67 }
68 }
69
70 impl TryFrom<fruntime::Data> for DataValue {
71 type Error = ();
72
73 fn try_from(val: fruntime::Data) -> Result<Self, Self::Error> {
74 match val {
75 fruntime::Data::Bytes(b) => Ok(Self::Bytes(b)),
76 fruntime::Data::String(b) => Ok(Self::String(b)),
77 fruntime::Data::Int64(b) => Ok(Self::Int64(b)),
78 fruntime::Data::Uint64(b) => Ok(Self::Uint64(b)),
79 _other_value => Err(()),
80 }
81 }
82 }
83
84 impl From<DataValue> for fruntime::Data {
85 fn from(val: DataValue) -> Self {
86 match val {
87 DataValue::Bytes(b) => Self::Bytes(b),
88 DataValue::String(b) => Self::String(b),
89 DataValue::Int64(b) => Self::Int64(b),
90 DataValue::Uint64(b) => Self::Uint64(b),
91 }
92 }
93 }
94
95 pub struct ConnectorReceiver {
97 pub stream: fruntime::ReceiverRequestStream,
98 }
99
100 impl From<fruntime::ReceiverRequestStream> for ConnectorReceiver {
101 fn from(stream: fruntime::ReceiverRequestStream) -> Self {
102 Self { stream }
103 }
104 }
105
106 impl Stream for ConnectorReceiver {
107 type Item = zx::Channel;
108
109 fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
110 let pinned_stream = pin!(&mut self.stream);
111 match pinned_stream.poll_next(cx) {
112 Poll::Pending => Poll::Pending,
113 Poll::Ready(Some(Ok(fruntime::ReceiverRequest::Receive { channel, .. }))) => {
114 Poll::Ready(Some(channel))
115 }
116 _ => Poll::Ready(None),
117 }
118 }
119 }
120
121 pub struct DirConnectorReceiver {
123 pub stream: fruntime::DirReceiverRequestStream,
124 }
125
126 impl From<fruntime::DirReceiverRequestStream> for DirConnectorReceiver {
127 fn from(stream: fruntime::DirReceiverRequestStream) -> Self {
128 Self { stream }
129 }
130 }
131
132 pub struct DirConnectorRequest {
133 pub channel: ServerEnd<fio::DirectoryMarker>,
134 pub path: String,
135 pub flags: fio::Flags,
136 }
137
138 impl Stream for DirConnectorReceiver {
139 type Item = DirConnectorRequest;
140
141 fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
142 let pinned_stream = pin!(&mut self.stream);
143 match pinned_stream.poll_next(cx) {
144 Poll::Pending => Poll::Pending,
145 Poll::Ready(Some(Ok(fruntime::DirReceiverRequest::Receive {
146 channel,
147 path,
148 rights,
149 ..
150 }))) => Poll::Ready(Some(DirConnectorRequest { channel, path, flags: rights })),
151 _ => Poll::Ready(None),
152 }
153 }
154 }
155
156 #[derive(Debug, Clone)]
160 pub enum Capability {
161 Connector(Connector),
162 ConnectorRouter(ConnectorRouter),
163 Data(Data),
164 DataRouter(DataRouter),
165 Dictionary(Dictionary),
166 DictionaryRouter(DictionaryRouter),
167 DirConnector(DirConnector),
168 DirConnectorRouter(DirConnectorRouter),
169 InstanceToken(InstanceToken),
170 }
171
172 impl Capability {
173 pub fn from_raw_with_proxy(
174 capabilities_proxy: fruntime::CapabilitiesProxy,
175 handle: zx::EventPair,
176 type_: fruntime::CapabilityType,
177 ) -> Self {
178 match type_ {
179 fruntime::CapabilityType::Data => Self::Data(Data { handle, capabilities_proxy }),
180 fruntime::CapabilityType::Connector => {
181 Self::Connector(Connector { handle, capabilities_proxy })
182 }
183 fruntime::CapabilityType::DirConnector => {
184 Self::DirConnector(DirConnector { handle, capabilities_proxy })
185 }
186 fruntime::CapabilityType::Dictionary => {
187 Self::Dictionary(Dictionary { handle, capabilities_proxy })
188 }
189 fruntime::CapabilityType::DataRouter => {
190 Self::DataRouter(DataRouter { handle, capabilities_proxy })
191 }
192 fruntime::CapabilityType::ConnectorRouter => {
193 Self::ConnectorRouter(ConnectorRouter { handle, capabilities_proxy })
194 }
195 fruntime::CapabilityType::DirConnectorRouter => {
196 Self::DirConnectorRouter(DirConnectorRouter { handle, capabilities_proxy })
197 }
198 fruntime::CapabilityType::DictionaryRouter => {
199 Self::DictionaryRouter(DictionaryRouter { handle, capabilities_proxy })
200 }
201 fruntime::CapabilityType::InstanceToken => {
202 Self::InstanceToken(InstanceToken { handle })
203 }
204 other_type => panic!("unknown capability type: {other_type:?}"),
205 }
206 }
207
208 pub fn as_event_pair(&self) -> &zx::EventPair {
209 match self {
210 Self::Data(data) => &data.handle,
211 Self::Connector(connector) => &connector.handle,
212 Self::DirConnector(dir_connector) => &dir_connector.handle,
213 Self::Dictionary(dictionary) => &dictionary.handle,
214 Self::DataRouter(data_router) => &data_router.handle,
215 Self::ConnectorRouter(connector_router) => &connector_router.handle,
216 Self::DirConnectorRouter(dir_connector_router) => &dir_connector_router.handle,
217 Self::DictionaryRouter(dictionary_router) => &dictionary_router.handle,
218 Self::InstanceToken(instance_token) => &instance_token.handle,
219 }
220 }
221 }
222
223 impl From<Data> for Capability {
224 fn from(val: Data) -> Self {
225 Self::Data(val)
226 }
227 }
228
229 impl From<Connector> for Capability {
230 fn from(val: Connector) -> Self {
231 Self::Connector(val)
232 }
233 }
234
235 impl From<DirConnector> for Capability {
236 fn from(val: DirConnector) -> Self {
237 Self::DirConnector(val)
238 }
239 }
240
241 impl From<Dictionary> for Capability {
242 fn from(val: Dictionary) -> Self {
243 Self::Dictionary(val)
244 }
245 }
246
247 impl From<DataRouter> for Capability {
248 fn from(val: DataRouter) -> Self {
249 Self::DataRouter(val)
250 }
251 }
252
253 impl From<ConnectorRouter> for Capability {
254 fn from(val: ConnectorRouter) -> Self {
255 Self::ConnectorRouter(val)
256 }
257 }
258
259 impl From<DirConnectorRouter> for Capability {
260 fn from(val: DirConnectorRouter) -> Self {
261 Self::DirConnectorRouter(val)
262 }
263 }
264
265 impl From<DictionaryRouter> for Capability {
266 fn from(val: DictionaryRouter) -> Self {
267 Self::DictionaryRouter(val)
268 }
269 }
270
271 impl From<InstanceToken> for Capability {
272 fn from(val: InstanceToken) -> Self {
273 Self::InstanceToken(val)
274 }
275 }
276
277 impl TryFrom<Capability> for Data {
278 type Error = ();
279 fn try_from(val: Capability) -> Result<Self, Self::Error> {
280 match val {
281 Capability::Data(val) => Ok(val),
282 _ => Err(()),
283 }
284 }
285 }
286
287 impl TryFrom<Capability> for Connector {
288 type Error = ();
289 fn try_from(val: Capability) -> Result<Self, Self::Error> {
290 match val {
291 Capability::Connector(val) => Ok(val),
292 _ => Err(()),
293 }
294 }
295 }
296
297 impl TryFrom<Capability> for DirConnector {
298 type Error = ();
299 fn try_from(val: Capability) -> Result<Self, Self::Error> {
300 match val {
301 Capability::DirConnector(val) => Ok(val),
302 _ => Err(()),
303 }
304 }
305 }
306
307 impl TryFrom<Capability> for Dictionary {
308 type Error = ();
309 fn try_from(val: Capability) -> Result<Self, Self::Error> {
310 match val {
311 Capability::Dictionary(val) => Ok(val),
312 _ => Err(()),
313 }
314 }
315 }
316
317 impl TryFrom<Capability> for DataRouter {
318 type Error = ();
319 fn try_from(val: Capability) -> Result<Self, Self::Error> {
320 match val {
321 Capability::DataRouter(val) => Ok(val),
322 _ => Err(()),
323 }
324 }
325 }
326
327 impl TryFrom<Capability> for ConnectorRouter {
328 type Error = ();
329 fn try_from(val: Capability) -> Result<Self, Self::Error> {
330 match val {
331 Capability::ConnectorRouter(val) => Ok(val),
332 _ => Err(()),
333 }
334 }
335 }
336
337 impl TryFrom<Capability> for DirConnectorRouter {
338 type Error = ();
339 fn try_from(val: Capability) -> Result<Self, Self::Error> {
340 match val {
341 Capability::DirConnectorRouter(val) => Ok(val),
342 _ => Err(()),
343 }
344 }
345 }
346
347 impl TryFrom<Capability> for DictionaryRouter {
348 type Error = ();
349 fn try_from(val: Capability) -> Result<Self, Self::Error> {
350 match val {
351 Capability::DictionaryRouter(val) => Ok(val),
352 _ => Err(()),
353 }
354 }
355 }
356
357 impl TryFrom<Capability> for InstanceToken {
358 type Error = ();
359 fn try_from(val: Capability) -> Result<Self, Self::Error> {
360 match val {
361 Capability::InstanceToken(val) => Ok(val),
362 _ => Err(()),
363 }
364 }
365 }
366
367 #[derive(Debug)]
369 pub struct Data {
370 pub handle: zx::EventPair,
372
373 pub capabilities_proxy: fruntime::CapabilitiesProxy,
376 }
377
378 impl From<zx::EventPair> for Data {
379 fn from(handle: zx::EventPair) -> Self {
380 Self {
381 handle,
382 capabilities_proxy: connect_to_protocol::<fruntime::CapabilitiesMarker>()
383 .expect("failed to connect to fuchsia.component.runtime.Capabilities"),
384 }
385 }
386 }
387
388 impl Data {
389 pub async fn new(value: DataValue) -> Self {
392 let proxy = connect_to_protocol::<fruntime::CapabilitiesMarker>()
393 .expect("failed to connect to fuchsia.component.runtime.Capabilities");
394 Self::new_with_proxy(proxy, value).await
395 }
396
397 pub async fn new_with_proxy(
399 capabilities_proxy: fruntime::CapabilitiesProxy,
400 value: DataValue,
401 ) -> Self {
402 let (handle, handle_other_end) = zx::EventPair::create();
403 capabilities_proxy
404 .data_create(handle_other_end, &value.into())
405 .await
406 .expect("failed to use fuchsia.component.runtime.Capabilities")
407 .expect(
408 "this should be impossible, we passed a valid handle with the correct rights",
409 );
410 Self { handle, capabilities_proxy }
411 }
412
413 pub async fn associate_with_handle(&self, other_handle: zx::EventPair) {
416 self.capabilities_proxy
417 .capability_associate_handle(
418 self.handle.duplicate_handle(zx::Rights::SAME_RIGHTS).expect(
419 "failed to duplicate handle, please only use handles with the duplicate right",
420 ),
421 other_handle,
422 )
423 .await
424 .expect("failed to use fuchsia.component.runtime.Capabilities")
425 .expect("failed to clone onto handle, does it have sufficient rights?");
426 }
427
428 pub async fn get_value(&self) -> DataValue {
429 self.capabilities_proxy
430 .data_get(self.handle.duplicate_handle(zx::Rights::SAME_RIGHTS).expect(
431 "failed to duplicate handle, please only use handles with the duplicate right",
432 ))
433 .await
434 .expect("failed to use fuchsia.component.runtime.Capabilities")
435 .expect("failed to get data value")
436 .try_into()
437 .expect("we were sent an invalid data value")
438 }
439 }
440
441 impl Clone for Data {
442 fn clone(&self) -> Self {
443 Self {
444 handle: self.handle.duplicate_handle(zx::Rights::SAME_RIGHTS).expect(
445 "failed to duplicate handle, please only use handles with the duplicate right",
446 ),
447 capabilities_proxy: self.capabilities_proxy.clone(),
448 }
449 }
450 }
451
452 #[derive(Debug)]
454 pub struct Connector {
455 pub handle: zx::EventPair,
457
458 pub capabilities_proxy: fruntime::CapabilitiesProxy,
461 }
462
463 impl From<zx::EventPair> for Connector {
464 fn from(handle: zx::EventPair) -> Self {
465 Self {
466 handle,
467 capabilities_proxy: connect_to_protocol::<fruntime::CapabilitiesMarker>()
468 .expect("failed to connect to fuchsia.component.runtime.Capabilities"),
469 }
470 }
471 }
472
473 impl Connector {
474 pub async fn new() -> (Self, ConnectorReceiver) {
477 let proxy = connect_to_protocol::<fruntime::CapabilitiesMarker>()
478 .expect("failed to connect to fuchsia.component.runtime.Capabilities");
479 Self::new_with_proxy(proxy).await
480 }
481
482 pub async fn new_with_proxy(
484 capabilities_proxy: fruntime::CapabilitiesProxy,
485 ) -> (Self, ConnectorReceiver) {
486 let (handle, handle_other_end) = zx::EventPair::create();
487 let (receiver_client_end, stream) = create_request_stream::<fruntime::ReceiverMarker>();
488 capabilities_proxy
489 .connector_create(handle_other_end, receiver_client_end)
490 .await
491 .expect("failed to use fuchsia.component.runtime.Capabilities")
492 .expect(
493 "this should be impossible, we passed a valid handle with the correct rights",
494 );
495 let connector = Self { handle, capabilities_proxy };
496 let receiver = ConnectorReceiver { stream };
497 (connector, receiver)
498 }
499
500 pub async fn associate_with_handle(&self, other_handle: zx::EventPair) {
503 self.capabilities_proxy
504 .capability_associate_handle(
505 self.handle.duplicate_handle(zx::Rights::SAME_RIGHTS).expect(
506 "failed to duplicate handle, please only use handles with the duplicate right",
507 ),
508 other_handle,
509 )
510 .await
511 .expect("failed to use fuchsia.component.runtime.Capabilities")
512 .expect("failed to clone onto handle, does it have sufficient rights?");
513 }
514
515 pub async fn connect(
516 &self,
517 channel: zx::Channel,
518 ) -> Result<(), fruntime::CapabilitiesError> {
519 self.capabilities_proxy
520 .connector_open(
521 self.handle.duplicate_handle(zx::Rights::SAME_RIGHTS).expect(
522 "failed to duplicate handle, please only use handles with the duplicate right",
523 ),
524 channel,
525 )
526 .await
527 .expect("failed to use fuchsia.component.runtime.Capabilities")
528 }
529 }
530
531 impl Clone for Connector {
532 fn clone(&self) -> Self {
533 Self {
534 handle: self.handle.duplicate_handle(zx::Rights::SAME_RIGHTS).expect(
535 "failed to duplicate handle, please only use handles with the duplicate right",
536 ),
537 capabilities_proxy: self.capabilities_proxy.clone(),
538 }
539 }
540 }
541
542 #[derive(Debug)]
545 pub struct DirConnector {
546 pub handle: zx::EventPair,
548
549 pub capabilities_proxy: fruntime::CapabilitiesProxy,
552 }
553
554 impl From<zx::EventPair> for DirConnector {
555 fn from(handle: zx::EventPair) -> Self {
556 Self {
557 handle,
558 capabilities_proxy: connect_to_protocol::<fruntime::CapabilitiesMarker>()
559 .expect("failed to connect to fuchsia.component.runtime.Capabilities"),
560 }
561 }
562 }
563
564 impl DirConnector {
565 pub async fn new() -> (Self, DirConnectorReceiver) {
568 let proxy = connect_to_protocol::<fruntime::CapabilitiesMarker>()
569 .expect("failed to connect to fuchsia.component.runtime.Capabilities");
570 Self::new_with_proxy(proxy).await
571 }
572
573 pub async fn new_with_proxy(
575 capabilities_proxy: fruntime::CapabilitiesProxy,
576 ) -> (Self, DirConnectorReceiver) {
577 let (handle, handle_other_end) = zx::EventPair::create();
578 let (receiver_client_end, stream) =
579 create_request_stream::<fruntime::DirReceiverMarker>();
580 capabilities_proxy
581 .dir_connector_create(handle_other_end, receiver_client_end)
582 .await
583 .expect("failed to use fuchsia.component.runtime.Capabilities")
584 .expect(
585 "this should be impossible, we passed a valid handle with the correct rights",
586 );
587 let connector = Self { handle, capabilities_proxy };
588 let receiver = DirConnectorReceiver { stream };
589 (connector, receiver)
590 }
591
592 pub async fn associate_with_handle(&self, other_handle: zx::EventPair) {
595 self.capabilities_proxy
596 .capability_associate_handle(
597 self.handle.duplicate_handle(zx::Rights::SAME_RIGHTS).expect(
598 "failed to duplicate handle, please only use handles with the duplicate right",
599 ),
600 other_handle,
601 )
602 .await
603 .expect("failed to use fuchsia.component.runtime.Capabilities")
604 .expect("failed to clone onto handle, does it have sufficient rights?");
605 }
606
607 pub async fn connect(
608 &self,
609 server_end: ServerEnd<fio::DirectoryMarker>,
610 flags: Option<fio::Flags>,
611 path: Option<String>,
612 ) -> Result<(), fruntime::CapabilitiesError> {
613 self.capabilities_proxy
614 .dir_connector_open(fruntime::CapabilitiesDirConnectorOpenRequest {
615 dir_connector: Some(self.handle.duplicate_handle(zx::Rights::SAME_RIGHTS).expect(
616 "failed to duplicate handle, please only use handles with the duplicate right",
617 )),
618 channel: Some(server_end),
619 flags,
620 path,
621 ..Default::default()
622 })
623 .await
624 .expect("failed to use fuchsia.component.runtime.Capabilities")
625 }
626 }
627
628 impl Clone for DirConnector {
629 fn clone(&self) -> Self {
630 Self {
631 handle: self.handle.duplicate_handle(zx::Rights::SAME_RIGHTS).expect(
632 "failed to duplicate handle, please only use handles with the duplicate right",
633 ),
634 capabilities_proxy: self.capabilities_proxy.clone(),
635 }
636 }
637 }
638
639 #[derive(Debug)]
641 pub struct Dictionary {
642 pub handle: zx::EventPair,
644
645 pub capabilities_proxy: fruntime::CapabilitiesProxy,
648 }
649
650 impl From<zx::EventPair> for Dictionary {
651 fn from(handle: zx::EventPair) -> Self {
652 Self {
653 handle,
654 capabilities_proxy: connect_to_protocol::<fruntime::CapabilitiesMarker>()
655 .expect("failed to connect to fuchsia.component.runtime.Capabilities"),
656 }
657 }
658 }
659
660 impl Dictionary {
661 pub async fn new() -> Self {
664 let proxy = connect_to_protocol::<fruntime::CapabilitiesMarker>()
665 .expect("failed to connect to fuchsia.component.runtime.Capabilities");
666 Self::new_with_proxy(proxy).await
667 }
668
669 pub async fn new_with_proxy(capabilities_proxy: fruntime::CapabilitiesProxy) -> Self {
671 let (handle, handle_other_end) = zx::EventPair::create();
672 capabilities_proxy
673 .dictionary_create(handle_other_end)
674 .await
675 .expect("failed to use fuchsia.component.runtime.Capabilities")
676 .expect(
677 "this should be impossible, we passed a valid handle with the correct rights",
678 );
679 Self { handle, capabilities_proxy }
680 }
681
682 pub async fn associate_with_handle(&self, other_handle: zx::EventPair) {
685 self.capabilities_proxy
686 .capability_associate_handle(
687 self.handle.duplicate_handle(zx::Rights::SAME_RIGHTS).expect(
688 "failed to duplicate handle, please only use handles with the duplicate right",
689 ),
690 other_handle,
691 )
692 .await
693 .expect("failed to use fuchsia.component.runtime.Capabilities")
694 .expect("failed to clone onto handle, does it have sufficient rights?");
695 }
696
697 pub async fn insert(&self, key: &str, value: impl Into<Capability>) {
698 let capability: Capability = value.into();
699 let dictionary = self.handle.duplicate_handle(zx::Rights::SAME_RIGHTS).expect(
700 "failed to duplicate handle, please only use handles with the duplicate right",
701 );
702 let handle =
703 capability.as_event_pair().duplicate_handle(zx::Rights::SAME_RIGHTS).expect(
704 "failed to duplicate handle, please only use handles with the duplicate right",
705 );
706 self.capabilities_proxy
707 .dictionary_insert(dictionary, key, handle)
708 .await
709 .expect("failed to use fuchsia.component.runtime.Capabilities")
710 .expect("failed to insert into dictionary")
711 }
712
713 pub async fn get(&self, key: &str) -> Option<Capability> {
714 let (handle, handle_other_end) = zx::EventPair::create();
715 let res = self
716 .capabilities_proxy
717 .dictionary_get(
718 self.handle.duplicate_handle(zx::Rights::SAME_RIGHTS).expect(
719 "failed to duplicate handle, please only use handles with the duplicate right",
720 ),
721 key,
722 handle_other_end,
723 )
724 .await
725 .expect("failed to use fuchsia.component.runtime.Capabilities");
726 match res {
727 Ok(type_) => Some(Capability::from_raw_with_proxy(
728 self.capabilities_proxy.clone(),
729 handle,
730 type_,
731 )),
732 Err(fruntime::CapabilitiesError::NoSuchCapability) => None,
733 Err(other_error) => panic!(
734 "this arm should be impossible, we passed a valid handle with the correct rights: {other_error:?}"
735 ),
736 }
737 }
738
739 pub async fn remove(&self, key: &str) -> Option<Capability> {
740 let (handle, handle_other_end) = zx::EventPair::create();
741 let res = self
742 .capabilities_proxy
743 .dictionary_remove(fruntime::CapabilitiesDictionaryRemoveRequest {
744 dictionary: Some(self.handle.duplicate_handle(zx::Rights::SAME_RIGHTS).expect(
745 "failed to duplicate handle, please only use handles with the duplicate right",
746 )),
747 key: Some(key.to_string()),
748 value: Some(handle_other_end),
749 ..Default::default()
750 })
751 .await
752 .expect("failed to use fuchsia.component.runtime.Capabilities");
753 match res {
754 Ok(type_) => Some(Capability::from_raw_with_proxy(
755 self.capabilities_proxy.clone(),
756 handle,
757 type_,
758 )),
759 Err(fruntime::CapabilitiesError::NoSuchCapability) => None,
760 Err(other_error) => panic!(
761 "this arm should be impossible, we passed a valid handle with the correct rights: {other_error:?}"
762 ),
763 }
764 }
765
766 pub async fn keys(&self) -> DictionaryKeysStream {
767 let (key_iterator_proxy, key_iterator_server_end) =
768 create_proxy::<fruntime::DictionaryKeyIteratorMarker>();
769 self.capabilities_proxy
770 .dictionary_iterate_keys(
771 self.handle.duplicate_handle(zx::Rights::SAME_RIGHTS).expect(
772 "failed to duplicate handle, please only use handles with the duplicate right",
773 ),
774 key_iterator_server_end,
775 )
776 .await
777 .expect("failed to use fuchsia.component.runtime.Capabilities")
778 .expect("failed to iterate keys");
779 DictionaryKeysStream { key_iterator_proxy, key_cache: vec![], more_keys_fut: None }
780 }
781 }
782
783 impl Clone for Dictionary {
784 fn clone(&self) -> Self {
785 Self {
786 handle: self.handle.duplicate_handle(zx::Rights::SAME_RIGHTS).expect(
787 "failed to duplicate handle, please only use handles with the duplicate right",
788 ),
789 capabilities_proxy: self.capabilities_proxy.clone(),
790 }
791 }
792 }
793
794 pub struct DictionaryKeysStream {
795 key_iterator_proxy: fruntime::DictionaryKeyIteratorProxy,
796 key_cache: Vec<String>,
797 more_keys_fut: Option<
798 fidl::client::QueryResponseFut<
799 Vec<String>,
800 fidl::encoding::DefaultFuchsiaResourceDialect,
801 >,
802 >,
803 }
804
805 impl Stream for DictionaryKeysStream {
806 type Item = String;
807
808 fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
809 if let Some(key) = self.key_cache.pop() {
810 return Poll::Ready(Some(key));
811 }
812 if self.more_keys_fut.is_none() {
813 self.more_keys_fut = Some(self.key_iterator_proxy.get_next());
814 }
815
816 let fut = self.more_keys_fut.as_mut().expect("we just checked if this was None");
817 let fut = pin!(fut);
818 match fut.poll(cx) {
819 Poll::Ready(Ok(mut keys)) if !keys.is_empty() => {
820 self.key_cache.append(&mut keys);
821 self.key_cache.reverse();
822 self.more_keys_fut = None;
823 Poll::Ready(self.key_cache.pop())
824 }
825 Poll::Pending => Poll::Pending,
826 _ => Poll::Ready(None),
827 }
828 }
829 }
830
831 #[derive(Debug)]
835 pub struct InstanceToken {
836 pub handle: zx::EventPair,
838 }
839
840 impl From<zx::EventPair> for InstanceToken {
841 fn from(handle: zx::EventPair) -> Self {
842 Self { handle }
843 }
844 }
845
846 impl InstanceToken {
847 pub async fn new() -> Self {
852 let proxy = connect_to_protocol::<fruntime::CapabilitiesMarker>()
853 .expect("failed to connect to fuchsia.component.runtime.Capabilities");
854 Self::new_with_proxy(proxy).await
855 }
856
857 pub async fn new_with_proxy(capabilities_proxy: fruntime::CapabilitiesProxy) -> Self {
859 let (handle, handle_other_end) = zx::EventPair::create();
860 capabilities_proxy
861 .instance_token_create(handle_other_end)
862 .await
863 .expect("failed to use fuchsia.component.runtime.Capabilities")
864 .expect(
865 "this should be impossible, we passed a valid handle with the correct rights",
866 );
867 Self { handle }
868 }
869 }
870
871 impl Clone for InstanceToken {
872 fn clone(&self) -> Self {
873 Self {
874 handle: self.handle.duplicate_handle(zx::Rights::SAME_RIGHTS).expect(
875 "failed to duplicate handle, please only use handles with the duplicate right",
876 ),
877 }
878 }
879 }
880
881 #[derive(Debug)]
886 pub struct ConnectorRouter {
887 pub handle: zx::EventPair,
889
890 pub capabilities_proxy: fruntime::CapabilitiesProxy,
893 }
894
895 impl From<zx::EventPair> for ConnectorRouter {
896 fn from(handle: zx::EventPair) -> Self {
897 Self {
898 handle,
899 capabilities_proxy: connect_to_protocol::<fruntime::CapabilitiesMarker>()
900 .expect("failed to connect to fuchsia.component.runtime.Capabilities"),
901 }
902 }
903 }
904
905 impl ConnectorRouter {
906 pub async fn new() -> (Self, ConnectorRouterReceiver) {
909 let proxy = connect_to_protocol::<fruntime::CapabilitiesMarker>()
910 .expect("failed to connect to fuchsia.component.runtime.Capabilities");
911 Self::new_with_proxy(proxy).await
912 }
913
914 pub async fn new_with_proxy(
916 capabilities_proxy: fruntime::CapabilitiesProxy,
917 ) -> (Self, ConnectorRouterReceiver) {
918 let (handle, handle_other_end) = zx::EventPair::create();
919 let (client_end, stream) = create_request_stream::<fruntime::ConnectorRouterMarker>();
920 capabilities_proxy
921 .connector_router_create(handle_other_end, client_end)
922 .await
923 .expect("failed to use fuchsia.component.runtime.Capabilities")
924 .expect(
925 "this should be impossible, we passed a valid handle with the correct rights",
926 );
927 let connector = Self { handle, capabilities_proxy };
928 let receiver = ConnectorRouterReceiver { stream };
929 (connector, receiver)
930 }
931
932 pub async fn associate_with_handle(&self, other_handle: zx::EventPair) {
935 self.capabilities_proxy
936 .capability_associate_handle(
937 self.handle.duplicate_handle(zx::Rights::SAME_RIGHTS).expect(
938 "failed to duplicate handle, please only use handles with the duplicate right",
939 ),
940 other_handle,
941 )
942 .await
943 .expect("failed to use fuchsia.component.runtime.Capabilities")
944 .expect("failed to clone onto handle, does it have sufficient rights?");
945 }
946
947 pub async fn route(
948 &self,
949 request: fruntime::RouteRequest,
950 instance_token: &InstanceToken,
951 ) -> Result<Option<Connector>, zx::Status> {
952 let (connector, connector_other_end) = zx::EventPair::create();
953 let res = self
954 .capabilities_proxy
955 .connector_router_route(
956 self.handle.duplicate_handle(zx::Rights::SAME_RIGHTS).expect(
957 "failed to duplicate handle, please only use handles with the duplicate right",
958 ),
959 &request,
960 instance_token.handle.duplicate_handle(zx::Rights::SAME_RIGHTS).expect(
961 "failed to duplicate handle, please only use handles with the duplicate right",
962 ),
963 connector_other_end,
964 )
965 .await
966 .expect("failed to use fuchsia.component.runtime.Capabilities");
967 match res.map_err(|s| zx::Status::from_raw(s))? {
968 fruntime::RouterResponse::Success => Ok(Some(Connector {
969 handle: connector,
970 capabilities_proxy: self.capabilities_proxy.clone(),
971 })),
972 fruntime::RouterResponse::Unavailable => Ok(None),
973 _ => Err(zx::Status::INTERNAL),
974 }
975 }
976 }
977
978 impl Clone for ConnectorRouter {
979 fn clone(&self) -> Self {
980 Self {
981 handle: self.handle.duplicate_handle(zx::Rights::SAME_RIGHTS).expect(
982 "failed to duplicate handle, please only use handles with the duplicate right",
983 ),
984 capabilities_proxy: self.capabilities_proxy.clone(),
985 }
986 }
987 }
988
989 pub struct ConnectorRouterReceiver {
991 pub stream: fruntime::ConnectorRouterRequestStream,
992 }
993
994 impl From<fruntime::ConnectorRouterRequestStream> for ConnectorRouterReceiver {
995 fn from(stream: fruntime::ConnectorRouterRequestStream) -> Self {
996 Self { stream }
997 }
998 }
999
1000 impl Stream for ConnectorRouterReceiver {
1001 type Item = (
1002 fruntime::RouteRequest,
1003 InstanceToken,
1004 zx::EventPair,
1005 fruntime::ConnectorRouterRouteResponder,
1006 );
1007
1008 fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
1009 let pinned_stream = pin!(&mut self.stream);
1010 match pinned_stream.poll_next(cx) {
1011 Poll::Pending => Poll::Pending,
1012 Poll::Ready(Some(Ok(fruntime::ConnectorRouterRequest::Route {
1013 request,
1014 instance_token,
1015 handle,
1016 responder,
1017 }))) => {
1018 let instance_token = InstanceToken { handle: instance_token };
1019 Poll::Ready(Some((request, instance_token, handle, responder)))
1020 }
1021 _ => Poll::Ready(None),
1022 }
1023 }
1024 }
1025
1026 impl ConnectorRouterReceiver {
1027 pub async fn handle_with<F>(mut self, f: F)
1028 where
1029 F: Fn(
1030 fruntime::RouteRequest,
1031 InstanceToken,
1032 ) -> BoxFuture<'static, Result<Option<Connector>, zx::Status>>
1033 + Sync
1034 + Send
1035 + 'static,
1036 {
1037 while let Some((request, instance_token, event_pair, responder)) = self.next().await {
1038 let res = match f(request, instance_token).await {
1039 Ok(Some(connector)) => {
1040 connector.associate_with_handle(event_pair).await;
1041 Ok(fruntime::RouterResponse::Success)
1042 }
1043 Ok(None) => Ok(fruntime::RouterResponse::Unavailable),
1044 Err(e) => Err(e.into_raw()),
1045 };
1046 let _ = responder.send(res);
1047 }
1048 }
1049 }
1050
1051 #[derive(Debug)]
1056 pub struct DirConnectorRouter {
1057 pub handle: zx::EventPair,
1059
1060 pub capabilities_proxy: fruntime::CapabilitiesProxy,
1063 }
1064
1065 impl From<zx::EventPair> for DirConnectorRouter {
1066 fn from(handle: zx::EventPair) -> Self {
1067 Self {
1068 handle,
1069 capabilities_proxy: connect_to_protocol::<fruntime::CapabilitiesMarker>()
1070 .expect("failed to connect to fuchsia.component.runtime.Capabilities"),
1071 }
1072 }
1073 }
1074
1075 impl DirConnectorRouter {
1076 pub async fn new() -> (Self, DirConnectorRouterReceiver) {
1079 let proxy = connect_to_protocol::<fruntime::CapabilitiesMarker>()
1080 .expect("failed to connect to fuchsia.component.runtime.Capabilities");
1081 Self::new_with_proxy(proxy).await
1082 }
1083
1084 pub async fn new_with_proxy(
1086 capabilities_proxy: fruntime::CapabilitiesProxy,
1087 ) -> (Self, DirConnectorRouterReceiver) {
1088 let (handle, handle_other_end) = zx::EventPair::create();
1089 let (client_end, stream) =
1090 create_request_stream::<fruntime::DirConnectorRouterMarker>();
1091 capabilities_proxy
1092 .dir_connector_router_create(handle_other_end, client_end)
1093 .await
1094 .expect("failed to use fuchsia.component.runtime.Capabilities")
1095 .expect(
1096 "this should be impossible, we passed a valid handle with the correct rights",
1097 );
1098 let connector = Self { handle, capabilities_proxy };
1099 let receiver = DirConnectorRouterReceiver { stream };
1100 (connector, receiver)
1101 }
1102
1103 pub async fn associate_with_handle(&self, other_handle: zx::EventPair) {
1106 self.capabilities_proxy
1107 .capability_associate_handle(
1108 self.handle.duplicate_handle(zx::Rights::SAME_RIGHTS).expect(
1109 "failed to duplicate handle, please only use handles with the duplicate right",
1110 ),
1111 other_handle,
1112 )
1113 .await
1114 .expect("failed to use fuchsia.component.runtime.Capabilities")
1115 .expect("failed to clone onto handle, does it have sufficient rights?");
1116 }
1117
1118 pub async fn route(
1119 &self,
1120 request: fruntime::RouteRequest,
1121 instance_token: &InstanceToken,
1122 ) -> Result<Option<DirConnector>, zx::Status> {
1123 let (connector, connector_other_end) = zx::EventPair::create();
1124 let res = self
1125 .capabilities_proxy
1126 .dir_connector_router_route(
1127 self.handle.duplicate_handle(zx::Rights::SAME_RIGHTS).expect(
1128 "failed to duplicate handle, please only use handles with the duplicate right",
1129 ),
1130 &request,
1131 instance_token.handle.duplicate_handle(zx::Rights::SAME_RIGHTS).expect(
1132 "failed to duplicate handle, please only use handles with the duplicate right",
1133 ),
1134 connector_other_end,
1135 )
1136 .await
1137 .expect("failed to use fuchsia.component.runtime.Capabilities");
1138 match res.map_err(|s| zx::Status::from_raw(s))? {
1139 fruntime::RouterResponse::Success => Ok(Some(DirConnector {
1140 handle: connector,
1141 capabilities_proxy: self.capabilities_proxy.clone(),
1142 })),
1143 fruntime::RouterResponse::Unavailable => Ok(None),
1144 _ => Err(zx::Status::INTERNAL),
1145 }
1146 }
1147 }
1148
1149 impl Clone for DirConnectorRouter {
1150 fn clone(&self) -> Self {
1151 Self {
1152 handle: self.handle.duplicate_handle(zx::Rights::SAME_RIGHTS).expect(
1153 "failed to duplicate handle, please only use handles with the duplicate right",
1154 ),
1155 capabilities_proxy: self.capabilities_proxy.clone(),
1156 }
1157 }
1158 }
1159
1160 pub struct DirConnectorRouterReceiver {
1162 pub stream: fruntime::DirConnectorRouterRequestStream,
1163 }
1164
1165 impl From<fruntime::DirConnectorRouterRequestStream> for DirConnectorRouterReceiver {
1166 fn from(stream: fruntime::DirConnectorRouterRequestStream) -> Self {
1167 Self { stream }
1168 }
1169 }
1170
1171 impl Stream for DirConnectorRouterReceiver {
1172 type Item = (
1173 fruntime::RouteRequest,
1174 InstanceToken,
1175 zx::EventPair,
1176 fruntime::DirConnectorRouterRouteResponder,
1177 );
1178
1179 fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
1180 let pinned_stream = pin!(&mut self.stream);
1181 match pinned_stream.poll_next(cx) {
1182 Poll::Pending => Poll::Pending,
1183 Poll::Ready(Some(Ok(fruntime::DirConnectorRouterRequest::Route {
1184 request,
1185 instance_token,
1186 handle,
1187 responder,
1188 }))) => {
1189 let instance_token = InstanceToken { handle: instance_token };
1190 Poll::Ready(Some((request, instance_token, handle, responder)))
1191 }
1192 _ => Poll::Ready(None),
1193 }
1194 }
1195 }
1196
1197 impl DirConnectorRouterReceiver {
1198 pub async fn handle_with<F>(mut self, f: F)
1199 where
1200 F: Fn(
1201 fruntime::RouteRequest,
1202 InstanceToken,
1203 ) -> BoxFuture<'static, Result<Option<DirConnector>, zx::Status>>
1204 + Sync
1205 + Send
1206 + 'static,
1207 {
1208 while let Some((request, instance_token, event_pair, responder)) = self.next().await {
1209 let res = match f(request, instance_token).await {
1210 Ok(Some(dictionary)) => {
1211 dictionary.associate_with_handle(event_pair).await;
1212 Ok(fruntime::RouterResponse::Success)
1213 }
1214 Ok(None) => Ok(fruntime::RouterResponse::Unavailable),
1215 Err(e) => Err(e.into_raw()),
1216 };
1217 let _ = responder.send(res);
1218 }
1219 }
1220 }
1221
1222 #[derive(Debug)]
1227 pub struct DictionaryRouter {
1228 pub handle: zx::EventPair,
1230
1231 pub capabilities_proxy: fruntime::CapabilitiesProxy,
1234 }
1235
1236 impl From<zx::EventPair> for DictionaryRouter {
1237 fn from(handle: zx::EventPair) -> Self {
1238 Self {
1239 handle,
1240 capabilities_proxy: connect_to_protocol::<fruntime::CapabilitiesMarker>()
1241 .expect("failed to connect to fuchsia.component.runtime.Capabilities"),
1242 }
1243 }
1244 }
1245
1246 impl DictionaryRouter {
1247 pub async fn new() -> (Self, DictionaryRouterReceiver) {
1250 let proxy = connect_to_protocol::<fruntime::CapabilitiesMarker>()
1251 .expect("failed to connect to fuchsia.component.runtime.Capabilities");
1252 Self::new_with_proxy(proxy).await
1253 }
1254
1255 pub async fn new_with_proxy(
1257 capabilities_proxy: fruntime::CapabilitiesProxy,
1258 ) -> (Self, DictionaryRouterReceiver) {
1259 let (handle, handle_other_end) = zx::EventPair::create();
1260 let (client_end, stream) = create_request_stream::<fruntime::DictionaryRouterMarker>();
1261 capabilities_proxy
1262 .dictionary_router_create(handle_other_end, client_end)
1263 .await
1264 .expect("failed to use fuchsia.component.runtime.Capabilities")
1265 .expect(
1266 "this should be impossible, we passed a valid handle with the correct rights",
1267 );
1268 let connector = Self { handle, capabilities_proxy };
1269 let receiver = DictionaryRouterReceiver { stream };
1270 (connector, receiver)
1271 }
1272
1273 pub async fn associate_with_handle(&self, other_handle: zx::EventPair) {
1276 self.capabilities_proxy
1277 .capability_associate_handle(
1278 self.handle.duplicate_handle(zx::Rights::SAME_RIGHTS).expect(
1279 "failed to duplicate handle, please only use handles with the duplicate right",
1280 ),
1281 other_handle,
1282 )
1283 .await
1284 .expect("failed to use fuchsia.component.runtime.Capabilities")
1285 .expect("failed to clone onto handle, does it have sufficient rights?");
1286 }
1287
1288 pub async fn route(
1289 &self,
1290 request: fruntime::RouteRequest,
1291 instance_token: &InstanceToken,
1292 ) -> Result<Option<Dictionary>, zx::Status> {
1293 let (connector, connector_other_end) = zx::EventPair::create();
1294 let res = self
1295 .capabilities_proxy
1296 .dictionary_router_route(
1297 self.handle.duplicate_handle(zx::Rights::SAME_RIGHTS).expect(
1298 "failed to duplicate handle, please only use handles with the duplicate right",
1299 ),
1300 &request,
1301 instance_token.handle.duplicate_handle(zx::Rights::SAME_RIGHTS).expect(
1302 "failed to duplicate handle, please only use handles with the duplicate right",
1303 ),
1304 connector_other_end,
1305 )
1306 .await
1307 .expect("failed to use fuchsia.component.runtime.Capabilities");
1308 match res.map_err(|s| zx::Status::from_raw(s))? {
1309 fruntime::RouterResponse::Success => Ok(Some(Dictionary {
1310 handle: connector,
1311 capabilities_proxy: self.capabilities_proxy.clone(),
1312 })),
1313 fruntime::RouterResponse::Unavailable => Ok(None),
1314 _ => Err(zx::Status::INTERNAL),
1315 }
1316 }
1317 }
1318
1319 impl Clone for DictionaryRouter {
1320 fn clone(&self) -> Self {
1321 Self {
1322 handle: self.handle.duplicate_handle(zx::Rights::SAME_RIGHTS).expect(
1323 "failed to duplicate handle, please only use handles with the duplicate right",
1324 ),
1325 capabilities_proxy: self.capabilities_proxy.clone(),
1326 }
1327 }
1328 }
1329
1330 pub struct DictionaryRouterReceiver {
1332 pub stream: fruntime::DictionaryRouterRequestStream,
1333 }
1334
1335 impl From<fruntime::DictionaryRouterRequestStream> for DictionaryRouterReceiver {
1336 fn from(stream: fruntime::DictionaryRouterRequestStream) -> Self {
1337 Self { stream }
1338 }
1339 }
1340
1341 impl Stream for DictionaryRouterReceiver {
1342 type Item = (
1343 fruntime::RouteRequest,
1344 InstanceToken,
1345 zx::EventPair,
1346 fruntime::DictionaryRouterRouteResponder,
1347 );
1348
1349 fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
1350 let pinned_stream = pin!(&mut self.stream);
1351 match pinned_stream.poll_next(cx) {
1352 Poll::Pending => Poll::Pending,
1353 Poll::Ready(Some(Ok(fruntime::DictionaryRouterRequest::Route {
1354 request,
1355 instance_token,
1356 handle,
1357 responder,
1358 }))) => {
1359 let instance_token = InstanceToken { handle: instance_token };
1360 Poll::Ready(Some((request, instance_token, handle, responder)))
1361 }
1362 _ => Poll::Ready(None),
1363 }
1364 }
1365 }
1366
1367 impl DictionaryRouterReceiver {
1368 pub async fn handle_with<F>(mut self, f: F)
1369 where
1370 F: Fn(
1371 fruntime::RouteRequest,
1372 InstanceToken,
1373 ) -> BoxFuture<'static, Result<Option<Dictionary>, zx::Status>>
1374 + Sync
1375 + Send
1376 + 'static,
1377 {
1378 while let Some((request, instance_token, event_pair, responder)) = self.next().await {
1379 let res = match f(request, instance_token).await {
1380 Ok(Some(dictionary)) => {
1381 dictionary.associate_with_handle(event_pair).await;
1382 Ok(fruntime::RouterResponse::Success)
1383 }
1384 Ok(None) => Ok(fruntime::RouterResponse::Unavailable),
1385 Err(e) => Err(e.into_raw()),
1386 };
1387 let _ = responder.send(res);
1388 }
1389 }
1390 }
1391
1392 #[derive(Debug)]
1397 pub struct DataRouter {
1398 pub handle: zx::EventPair,
1400
1401 pub capabilities_proxy: fruntime::CapabilitiesProxy,
1404 }
1405
1406 impl From<zx::EventPair> for DataRouter {
1407 fn from(handle: zx::EventPair) -> Self {
1408 Self {
1409 handle,
1410 capabilities_proxy: connect_to_protocol::<fruntime::CapabilitiesMarker>()
1411 .expect("failed to connect to fuchsia.component.runtime.Capabilities"),
1412 }
1413 }
1414 }
1415
1416 impl DataRouter {
1417 pub async fn new() -> (Self, DataRouterReceiver) {
1420 let proxy = connect_to_protocol::<fruntime::CapabilitiesMarker>()
1421 .expect("failed to connect to fuchsia.component.runtime.Capabilities");
1422 Self::new_with_proxy(proxy).await
1423 }
1424
1425 pub async fn new_with_proxy(
1427 capabilities_proxy: fruntime::CapabilitiesProxy,
1428 ) -> (Self, DataRouterReceiver) {
1429 let (handle, handle_other_end) = zx::EventPair::create();
1430 let (client_end, stream) = create_request_stream::<fruntime::DataRouterMarker>();
1431 capabilities_proxy
1432 .data_router_create(handle_other_end, client_end)
1433 .await
1434 .expect("failed to use fuchsia.component.runtime.Capabilities")
1435 .expect(
1436 "this should be impossible, we passed a valid handle with the correct rights",
1437 );
1438 let connector = Self { handle, capabilities_proxy };
1439 let receiver = DataRouterReceiver { stream };
1440 (connector, receiver)
1441 }
1442
1443 pub async fn associate_with_handle(&self, other_handle: zx::EventPair) {
1446 self.capabilities_proxy
1447 .capability_associate_handle(
1448 self.handle.duplicate_handle(zx::Rights::SAME_RIGHTS).expect(
1449 "failed to duplicate handle, please only use handles with the duplicate right",
1450 ),
1451 other_handle,
1452 )
1453 .await
1454 .expect("failed to use fuchsia.component.runtime.Capabilities")
1455 .expect("failed to clone onto handle, does it have sufficient rights?");
1456 }
1457
1458 pub async fn route(
1459 &self,
1460 request: fruntime::RouteRequest,
1461 instance_token: &InstanceToken,
1462 ) -> Result<Option<Data>, zx::Status> {
1463 let (connector, connector_other_end) = zx::EventPair::create();
1464 let res = self
1465 .capabilities_proxy
1466 .data_router_route(
1467 self.handle.duplicate_handle(zx::Rights::SAME_RIGHTS).expect(
1468 "failed to duplicate handle, please only use handles with the duplicate right",
1469 ),
1470 &request,
1471 instance_token.handle.duplicate_handle(zx::Rights::SAME_RIGHTS).expect(
1472 "failed to duplicate handle, please only use handles with the duplicate right",
1473 ),
1474 connector_other_end,
1475 )
1476 .await
1477 .expect("failed to use fuchsia.component.runtime.Capabilities");
1478 match res.map_err(|s| zx::Status::from_raw(s))? {
1479 fruntime::RouterResponse::Success => Ok(Some(Data {
1480 handle: connector,
1481 capabilities_proxy: self.capabilities_proxy.clone(),
1482 })),
1483 fruntime::RouterResponse::Unavailable => Ok(None),
1484 _ => Err(zx::Status::INTERNAL),
1485 }
1486 }
1487 }
1488
1489 impl Clone for DataRouter {
1490 fn clone(&self) -> Self {
1491 Self {
1492 handle: self.handle.duplicate_handle(zx::Rights::SAME_RIGHTS).expect(
1493 "failed to duplicate handle, please only use handles with the duplicate right",
1494 ),
1495 capabilities_proxy: self.capabilities_proxy.clone(),
1496 }
1497 }
1498 }
1499
1500 pub struct DataRouterReceiver {
1502 pub stream: fruntime::DataRouterRequestStream,
1503 }
1504
1505 impl From<fruntime::DataRouterRequestStream> for DataRouterReceiver {
1506 fn from(stream: fruntime::DataRouterRequestStream) -> Self {
1507 Self { stream }
1508 }
1509 }
1510
1511 impl Stream for DataRouterReceiver {
1512 type Item = (
1513 fruntime::RouteRequest,
1514 InstanceToken,
1515 zx::EventPair,
1516 fruntime::DataRouterRouteResponder,
1517 );
1518
1519 fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
1520 let pinned_stream = pin!(&mut self.stream);
1521 match pinned_stream.poll_next(cx) {
1522 Poll::Pending => Poll::Pending,
1523 Poll::Ready(Some(Ok(fruntime::DataRouterRequest::Route {
1524 request,
1525 instance_token,
1526 handle,
1527 responder,
1528 }))) => {
1529 let instance_token = InstanceToken { handle: instance_token };
1530 Poll::Ready(Some((request, instance_token, handle, responder)))
1531 }
1532 _ => Poll::Ready(None),
1533 }
1534 }
1535 }
1536
1537 impl DataRouterReceiver {
1538 pub async fn handle_with<F>(mut self, f: F)
1539 where
1540 F: Fn(
1541 fruntime::RouteRequest,
1542 InstanceToken,
1543 ) -> BoxFuture<'static, Result<Option<Data>, zx::Status>>
1544 + Sync
1545 + Send
1546 + 'static,
1547 {
1548 while let Some((request, instance_token, event_pair, responder)) = self.next().await {
1549 let res = match f(request, instance_token).await {
1550 Ok(Some(data)) => {
1551 data.associate_with_handle(event_pair).await;
1552 Ok(fruntime::RouterResponse::Success)
1553 }
1554 Ok(None) => Ok(fruntime::RouterResponse::Unavailable),
1555 Err(e) => Err(e.into_raw()),
1556 };
1557 let _ = responder.send(res);
1558 }
1559 }
1560 }
1561
1562 #[cfg(test)]
1563 mod tests {
1564 use super::*;
1565 use assert_matches::assert_matches;
1566 use futures::StreamExt;
1567 use std::collections::HashSet;
1568 use zx::AsHandleRef;
1569
1570 #[fuchsia::test]
1571 async fn connector_test() {
1572 let (connector, mut receiver) = Connector::new().await;
1573 let (c1, c2) = zx::Channel::create();
1574 connector.connect(c1).await.unwrap();
1575 let c1 = receiver.next().await.unwrap();
1576 assert_eq!(c1.basic_info().unwrap().koid, c2.basic_info().unwrap().related_koid);
1577 }
1578
1579 #[fuchsia::test]
1580 async fn dir_connector_test() {
1581 let (dir_connector, mut dir_receiver) = DirConnector::new().await;
1582 let (client_end, server_end) =
1583 fidl::endpoints::create_endpoints::<fio::DirectoryMarker>();
1584 dir_connector
1585 .connect(server_end, Some(fio::PERM_WRITABLE), Some("foo/bar".to_string()))
1586 .await
1587 .unwrap();
1588 let dir_request = dir_receiver.next().await.unwrap();
1589 assert_eq!(
1590 client_end.as_handle_ref().basic_info().unwrap().koid,
1591 dir_request.channel.as_handle_ref().basic_info().unwrap().related_koid
1592 );
1593 assert_eq!("foo/bar", dir_request.path);
1594 assert_eq!(fio::PERM_WRITABLE, dir_request.flags);
1595 }
1596
1597 #[fuchsia::test]
1598 async fn dictionary_test() {
1599 let dictionary = Dictionary::new().await;
1600 assert!(dictionary.get("foo").await.is_none());
1601 dictionary.insert("foo", Dictionary::new().await).await;
1602 assert_matches!(dictionary.get("foo").await, Some(Capability::Dictionary(_)));
1603 let mut keys_stream = dictionary.keys().await;
1604 assert_eq!(Some("foo".to_string()), keys_stream.next().await);
1605 assert_eq!(None, keys_stream.next().await);
1606
1607 assert_matches!(dictionary.remove("foo").await, Some(Capability::Dictionary(_)));
1608 assert_matches!(dictionary.remove("foo").await, None);
1609 assert!(dictionary.get("foo").await.is_none());
1610 }
1611
1612 #[fuchsia::test]
1613 async fn dictionary_key_iterator_many_keys_test() {
1614 let dictionary = Dictionary::new().await;
1615
1616 let mut keys = HashSet::new();
1618 for i in 0..zx::sys::ZX_CHANNEL_MAX_MSG_BYTES / 50 {
1619 keys.insert(format!("{:0100}", i));
1620 }
1621 for key in keys.iter() {
1622 dictionary.insert(key.as_str(), Dictionary::new().await).await;
1623 }
1624
1625 let mut keys_stream = dictionary.keys().await;
1626 let mut returned_keys = HashSet::new();
1627 while let Some(key) = keys_stream.next().await {
1628 returned_keys.insert(key);
1629 }
1630 assert_eq!(keys, returned_keys);
1631 }
1632
1633 #[fuchsia::test]
1634 async fn all_capabilities_into_and_out_of_a_dictionary_test() {
1635 let dictionary = Dictionary::new().await;
1636 let (connector, _receiver) = Connector::new().await;
1637 dictionary.insert("connector", connector).await;
1638 let (dir_connector, _dir_receiver) = DirConnector::new().await;
1639 dictionary.insert("dir_connector", dir_connector).await;
1640 dictionary.insert("dictionary", Dictionary::new().await).await;
1641 dictionary.insert("data", Data::new(DataValue::Int64(1)).await).await;
1642 let (connector_router, _connector_router_receiver) = ConnectorRouter::new().await;
1643 dictionary.insert("connector_router", connector_router).await;
1644 let (dir_connector_router, _dir_connector_router_receiver) =
1645 DirConnectorRouter::new().await;
1646 dictionary.insert("dir_connector_router", dir_connector_router).await;
1647 let (dictionary_router, _dictionary_router_receiver) = DictionaryRouter::new().await;
1648 dictionary.insert("dictionary_router", dictionary_router).await;
1649 let (data_router, _data_router_receiver) = DataRouter::new().await;
1650 dictionary.insert("data_router", data_router).await;
1651 dictionary.insert("instance_token", InstanceToken::new().await).await;
1652
1653 assert_matches!(dictionary.get("connector").await, Some(Capability::Connector(_)));
1654 assert_matches!(
1655 dictionary.get("dir_connector").await,
1656 Some(Capability::DirConnector(_))
1657 );
1658 assert_matches!(dictionary.get("dictionary").await, Some(Capability::Dictionary(_)));
1659 assert_matches!(dictionary.get("data").await, Some(Capability::Data(_)));
1660 assert_matches!(
1661 dictionary.get("connector_router").await,
1662 Some(Capability::ConnectorRouter(_))
1663 );
1664 assert_matches!(
1665 dictionary.get("dir_connector_router").await,
1666 Some(Capability::DirConnectorRouter(_))
1667 );
1668 assert_matches!(
1669 dictionary.get("dictionary_router").await,
1670 Some(Capability::DictionaryRouter(_))
1671 );
1672 assert_matches!(dictionary.get("data_router").await, Some(Capability::DataRouter(_)));
1673 assert_matches!(
1674 dictionary.get("instance_token").await,
1675 Some(Capability::InstanceToken(_))
1676 );
1677 }
1678
1679 #[fuchsia::test]
1680 async fn data_test() {
1681 let data = Data::new(DataValue::Uint64(100)).await;
1682 assert_eq!(DataValue::Uint64(100), data.get_value().await);
1683 }
1684
1685 #[fuchsia::test]
1686 async fn connector_router_test() {
1687 let (connector_router, mut connector_router_receiver) = ConnectorRouter::new().await;
1688
1689 let result_fut = fuchsia_async::Task::spawn(async move {
1690 let instance_token = InstanceToken::new().await;
1691 connector_router.route(fruntime::RouteRequest::default(), &instance_token).await
1692 });
1693
1694 let (_route_request, _instance_token, handle, responder) =
1695 connector_router_receiver.next().await.unwrap();
1696 let (connector, mut receiver) = Connector::new().await;
1697 connector.associate_with_handle(handle).await;
1698 responder.send(Ok(fruntime::RouterResponse::Success)).unwrap();
1699
1700 let connector = match result_fut.await {
1701 Ok(Some(connector)) => connector,
1702 other_value => panic!("unexpected route result: {other_value:?}"),
1703 };
1704
1705 let (c1, c2) = zx::Channel::create();
1706 connector.connect(c1).await.unwrap();
1707 let c1 = receiver.next().await.unwrap();
1708 assert_eq!(c1.basic_info().unwrap().koid, c2.basic_info().unwrap().related_koid);
1709 }
1710
1711 #[fuchsia::test]
1712 async fn dir_connector_router_test() {
1713 let (dir_connector_router, mut dir_connector_router_receiver) =
1714 DirConnectorRouter::new().await;
1715
1716 let result_fut = fuchsia_async::Task::spawn(async move {
1717 let instance_token = InstanceToken::new().await;
1718 dir_connector_router.route(fruntime::RouteRequest::default(), &instance_token).await
1719 });
1720
1721 let (_route_request, _instance_token, handle, responder) =
1722 dir_connector_router_receiver.next().await.unwrap();
1723 let (dir_connector, mut dir_receiver) = DirConnector::new().await;
1724 dir_connector.associate_with_handle(handle).await;
1725 responder.send(Ok(fruntime::RouterResponse::Success)).unwrap();
1726
1727 let dir_connector = match result_fut.await {
1728 Ok(Some(dir_connector)) => dir_connector,
1729 other_value => panic!("unexpected route result: {other_value:?}"),
1730 };
1731
1732 let (client_end, server_end) =
1733 fidl::endpoints::create_endpoints::<fio::DirectoryMarker>();
1734 dir_connector
1735 .connect(server_end, Some(fio::PERM_WRITABLE), Some("foo/bar".to_string()))
1736 .await
1737 .unwrap();
1738 let dir_request = dir_receiver.next().await.unwrap();
1739 assert_eq!(
1740 client_end.as_handle_ref().basic_info().unwrap().koid,
1741 dir_request.channel.as_handle_ref().basic_info().unwrap().related_koid
1742 );
1743 assert_eq!("foo/bar", dir_request.path);
1744 assert_eq!(fio::PERM_WRITABLE, dir_request.flags);
1745 }
1746
1747 #[fuchsia::test]
1748 async fn dictionary_router_test() {
1749 let (dictionary_router, mut dictionary_router_receiver) = DictionaryRouter::new().await;
1750
1751 let result_fut = fuchsia_async::Task::spawn(async move {
1752 let instance_token = InstanceToken::new().await;
1753 dictionary_router.route(fruntime::RouteRequest::default(), &instance_token).await
1754 });
1755
1756 let (_route_request, _instance_token, handle, responder) =
1757 dictionary_router_receiver.next().await.unwrap();
1758 let dictionary = Dictionary::new().await;
1759 dictionary.insert("foo", Data::new(DataValue::String("bar".to_string())).await).await;
1760 dictionary.associate_with_handle(handle).await;
1761 responder.send(Ok(fruntime::RouterResponse::Success)).unwrap();
1762
1763 let dictionary = match result_fut.await {
1764 Ok(Some(dictionary)) => dictionary,
1765 other_value => panic!("unexpected route result: {other_value:?}"),
1766 };
1767
1768 let data = match dictionary.get("foo").await {
1769 Some(Capability::Data(data)) => data,
1770 other_value => panic!("unexpected dictionary contents: {other_value:?}"),
1771 };
1772 assert_eq!(data.get_value().await, DataValue::String("bar".to_string()));
1773 }
1774 }
1775}