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