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