1use cm_rust_derive::{
6 ExposeDeclCommon, ExposeDeclCommonAlwaysRequired, FidlDecl, OfferDeclCommon,
7 OfferDeclCommonNoAvailability, UseDeclCommon,
8};
9use cm_types::{AllowedOffers, BorrowedSeparatedPath, LongName, Name, Path, RelativePath, Url};
10use from_enum::FromEnum;
11use std::collections::{BTreeMap, HashMap};
12use std::fmt;
13use std::hash::Hash;
14use strum_macros::EnumIter;
15use thiserror::Error;
16use {
17 fidl_fuchsia_component_decl as fdecl, fidl_fuchsia_data as fdata, fidl_fuchsia_io as fio,
18 fidl_fuchsia_process as fprocess, fidl_fuchsia_sys2 as fsys,
19};
20
21#[cfg(feature = "serde")]
22use serde::{Deserialize, Serialize};
23
24#[cfg(feature = "serde")]
25mod serde_ext;
26
27pub trait FidlIntoNative<T> {
29 fn fidl_into_native(self) -> T;
30}
31
32impl<Native, Fidl> FidlIntoNative<Vec<Native>> for Vec<Fidl>
33where
34 Fidl: FidlIntoNative<Native>,
35{
36 fn fidl_into_native(self) -> Vec<Native> {
37 self.into_iter().map(|s| s.fidl_into_native()).collect()
38 }
39}
40
41pub trait NativeIntoFidl<T> {
42 fn native_into_fidl(self) -> T;
43}
44
45impl<Native, Fidl> NativeIntoFidl<Vec<Fidl>> for Vec<Native>
46where
47 Native: NativeIntoFidl<Fidl>,
48{
49 fn native_into_fidl(self) -> Vec<Fidl> {
50 self.into_iter().map(|s| s.native_into_fidl()).collect()
51 }
52}
53
54impl FidlIntoNative<Name> for String {
55 fn fidl_into_native(self) -> Name {
56 self.parse().unwrap()
58 }
59}
60
61impl NativeIntoFidl<String> for Name {
62 fn native_into_fidl(self) -> String {
63 self.to_string()
64 }
65}
66
67impl FidlIntoNative<LongName> for String {
68 fn fidl_into_native(self) -> LongName {
69 self.parse().unwrap()
71 }
72}
73
74impl NativeIntoFidl<String> for LongName {
75 fn native_into_fidl(self) -> String {
76 self.to_string()
77 }
78}
79
80impl FidlIntoNative<Path> for String {
81 fn fidl_into_native(self) -> Path {
82 self.parse().unwrap()
84 }
85}
86
87impl NativeIntoFidl<String> for Path {
88 fn native_into_fidl(self) -> String {
89 self.to_string()
90 }
91}
92
93impl FidlIntoNative<RelativePath> for String {
94 fn fidl_into_native(self) -> RelativePath {
95 self.parse().unwrap()
97 }
98}
99
100impl NativeIntoFidl<String> for RelativePath {
101 fn native_into_fidl(self) -> String {
102 self.to_string()
103 }
104}
105
106impl NativeIntoFidl<Option<String>> for RelativePath {
107 fn native_into_fidl(self) -> Option<String> {
108 if self.is_dot() {
109 None
110 } else {
111 Some(self.to_string())
112 }
113 }
114}
115
116impl FidlIntoNative<Url> for String {
117 fn fidl_into_native(self) -> Url {
118 self.parse().unwrap()
120 }
121}
122
123impl NativeIntoFidl<String> for Url {
124 fn native_into_fidl(self) -> String {
125 self.to_string()
126 }
127}
128
129macro_rules! fidl_translations_identical {
131 ($into_type:ty) => {
132 impl FidlIntoNative<$into_type> for $into_type {
133 fn fidl_into_native(self) -> $into_type {
134 self
135 }
136 }
137 impl NativeIntoFidl<$into_type> for $into_type {
138 fn native_into_fidl(self) -> Self {
139 self
140 }
141 }
142 };
143}
144
145macro_rules! fidl_translations_from_into {
148 ($native_type:ty, $fidl_type:ty) => {
149 impl FidlIntoNative<$native_type> for $fidl_type {
150 fn fidl_into_native(self) -> $native_type {
151 self.into()
152 }
153 }
154 impl NativeIntoFidl<$fidl_type> for $native_type {
155 fn native_into_fidl(self) -> $fidl_type {
156 self.into()
157 }
158 }
159 };
160}
161
162macro_rules! fidl_translations_symmetrical_enums {
168($fidl_type:ty , $native_type:ty, $($variant: ident),*) => {
169 impl FidlIntoNative<$native_type> for $fidl_type {
170 fn fidl_into_native(self) -> $native_type {
171 match self {
172 $( <$fidl_type>::$variant => <$native_type>::$variant, )*
173 }
174 }
175 }
176 impl NativeIntoFidl<$fidl_type> for $native_type {
177 fn native_into_fidl(self) -> $fidl_type {
178 match self {
179 $( <$native_type>::$variant => <$fidl_type>::$variant, )*
180 }
181 }
182 }
183 };
184}
185
186#[derive(FidlDecl, Debug, Clone, PartialEq, Default)]
187#[fidl_decl(fidl_table = "fdecl::Component")]
188pub struct ComponentDecl {
189 pub program: Option<ProgramDecl>,
190 pub uses: Vec<UseDecl>,
191 pub exposes: Vec<ExposeDecl>,
192 pub offers: Vec<OfferDecl>,
193 pub capabilities: Vec<CapabilityDecl>,
194 pub children: Vec<ChildDecl>,
195 pub collections: Vec<CollectionDecl>,
196 pub facets: Option<fdata::Dictionary>,
197 pub environments: Vec<EnvironmentDecl>,
198 pub config: Option<ConfigDecl>,
199}
200
201impl ComponentDecl {
202 #[cfg(fuchsia_api_level_at_least = "HEAD")]
204 pub fn get_runner(&self) -> Option<UseRunnerDecl> {
205 self.program
206 .as_ref()
207 .and_then(|p| p.runner.as_ref())
208 .map(|r| UseRunnerDecl {
209 source: UseSource::Environment,
210 source_name: r.clone(),
211 source_dictionary: Default::default(),
212 })
213 .or_else(|| {
214 self.uses.iter().find_map(|u| match u {
215 UseDecl::Runner(r) => Some(r.clone()),
216 _ => None,
217 })
218 })
219 }
220
221 pub fn find_storage_source<'a>(&'a self, storage_name: &Name) -> Option<&'a StorageDecl> {
223 self.capabilities.iter().find_map(|c| match c {
224 CapabilityDecl::Storage(s) if &s.name == storage_name => Some(s),
225 _ => None,
226 })
227 }
228
229 pub fn find_protocol_source<'a>(&'a self, protocol_name: &Name) -> Option<&'a ProtocolDecl> {
231 self.capabilities.iter().find_map(|c| match c {
232 CapabilityDecl::Protocol(r) if &r.name == protocol_name => Some(r),
233 _ => None,
234 })
235 }
236
237 pub fn find_directory_source<'a>(&'a self, directory_name: &Name) -> Option<&'a DirectoryDecl> {
239 self.capabilities.iter().find_map(|c| match c {
240 CapabilityDecl::Directory(r) if &r.name == directory_name => Some(r),
241 _ => None,
242 })
243 }
244
245 pub fn find_runner_source<'a>(&'a self, runner_name: &Name) -> Option<&'a RunnerDecl> {
247 self.capabilities.iter().find_map(|c| match c {
248 CapabilityDecl::Runner(r) if &r.name == runner_name => Some(r),
249 _ => None,
250 })
251 }
252
253 pub fn find_resolver_source<'a>(&'a self, resolver_name: &Name) -> Option<&'a ResolverDecl> {
255 self.capabilities.iter().find_map(|c| match c {
256 CapabilityDecl::Resolver(r) if &r.name == resolver_name => Some(r),
257 _ => None,
258 })
259 }
260
261 pub fn find_collection<'a>(&'a self, collection_name: &str) -> Option<&'a CollectionDecl> {
263 self.collections.iter().find(|c| c.name == collection_name)
264 }
265
266 pub fn is_protocol_exposed_to_framework(&self, in_target_name: &Name) -> bool {
268 self.exposes.iter().any(|expose| match expose {
269 ExposeDecl::Protocol(ExposeProtocolDecl { target, target_name, .. })
270 if target == &ExposeTarget::Framework =>
271 {
272 target_name == in_target_name
273 }
274 _ => false,
275 })
276 }
277
278 pub fn uses_protocol(&self, source_name: &Name) -> bool {
280 self.uses.iter().any(|use_decl| match use_decl {
281 UseDecl::Protocol(ls) => &ls.source_name == source_name,
282 _ => false,
283 })
284 }
285}
286
287pub use cm_types::Availability;
288
289fidl_translations_symmetrical_enums!(
290 fdecl::Availability,
291 Availability,
292 Required,
293 Optional,
294 SameAsTarget,
295 Transitional
296);
297
298pub use cm_types::DeliveryType;
299
300#[cfg(fuchsia_api_level_at_least = "HEAD")]
301impl FidlIntoNative<DeliveryType> for fdecl::DeliveryType {
302 fn fidl_into_native(self) -> DeliveryType {
303 self.try_into().unwrap()
304 }
305}
306
307#[cfg(fuchsia_api_level_at_least = "HEAD")]
308impl NativeIntoFidl<fdecl::DeliveryType> for DeliveryType {
309 fn native_into_fidl(self) -> fdecl::DeliveryType {
310 self.into()
311 }
312}
313
314pub trait SourcePath {
315 fn source_path(&self) -> BorrowedSeparatedPath<'_>;
316 fn is_from_dictionary(&self) -> bool {
317 !self.source_path().dirname.is_dot()
318 }
319}
320
321#[cfg_attr(
322 feature = "serde",
323 derive(Deserialize, Serialize),
324 serde(tag = "type", rename_all = "snake_case")
325)]
326#[derive(FidlDecl, FromEnum, Debug, Clone, PartialEq, Eq)]
327#[fidl_decl(fidl_union = "fdecl::Use")]
328pub enum UseDecl {
329 Service(UseServiceDecl),
330 Protocol(UseProtocolDecl),
331 Directory(UseDirectoryDecl),
332 Storage(UseStorageDecl),
333 EventStream(UseEventStreamDecl),
334 #[cfg(fuchsia_api_level_at_least = "HEAD")]
335 Runner(UseRunnerDecl),
336 #[cfg(fuchsia_api_level_at_least = "20")]
337 Config(UseConfigurationDecl),
338}
339
340#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
341#[derive(FidlDecl, UseDeclCommon, Debug, Clone, PartialEq, Eq)]
342#[fidl_decl(fidl_table = "fdecl::UseService", source_path = "dictionary")]
343pub struct UseServiceDecl {
344 pub source: UseSource,
345 pub source_name: Name,
346 #[cfg(fuchsia_api_level_at_least = "25")]
347 #[fidl_decl(default_preserve_none)]
348 pub source_dictionary: RelativePath,
349 pub target_path: Path,
350 pub dependency_type: DependencyType,
351 #[fidl_decl(default)]
352 pub availability: Availability,
353}
354
355#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
356#[derive(FidlDecl, UseDeclCommon, Debug, Clone, PartialEq, Eq)]
357#[fidl_decl(fidl_table = "fdecl::UseProtocol", source_path = "dictionary")]
358pub struct UseProtocolDecl {
359 pub source: UseSource,
360 pub source_name: Name,
361 #[cfg(fuchsia_api_level_at_least = "25")]
362 #[fidl_decl(default_preserve_none)]
363 pub source_dictionary: RelativePath,
364 pub target_path: Path,
365 pub dependency_type: DependencyType,
366 #[fidl_decl(default)]
367 pub availability: Availability,
368}
369
370#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
371#[derive(FidlDecl, UseDeclCommon, Debug, Clone, PartialEq, Eq)]
372#[fidl_decl(fidl_table = "fdecl::UseDirectory", source_path = "dictionary")]
373pub struct UseDirectoryDecl {
374 pub source: UseSource,
375 pub source_name: Name,
376 #[cfg(fuchsia_api_level_at_least = "25")]
377 #[fidl_decl(default_preserve_none)]
378 pub source_dictionary: RelativePath,
379 pub target_path: Path,
380
381 #[cfg_attr(
382 feature = "serde",
383 serde(
384 deserialize_with = "serde_ext::deserialize_fio_operations",
385 serialize_with = "serde_ext::serialize_fio_operations"
386 )
387 )]
388 pub rights: fio::Operations,
389
390 #[fidl_decl(default_preserve_none)]
391 pub subdir: RelativePath,
392 pub dependency_type: DependencyType,
393 #[fidl_decl(default)]
394 pub availability: Availability,
395}
396
397#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
398#[derive(FidlDecl, Debug, Clone, PartialEq, Eq)]
399#[fidl_decl(fidl_table = "fdecl::UseStorage", source_path = "name_only")]
400pub struct UseStorageDecl {
401 pub source_name: Name,
402 pub target_path: Path,
403 #[fidl_decl(default)]
404 pub availability: Availability,
405}
406
407impl SourceName for UseStorageDecl {
408 fn source_name(&self) -> &Name {
409 &self.source_name
410 }
411}
412
413impl UseDeclCommon for UseStorageDecl {
414 fn source(&self) -> &UseSource {
415 &UseSource::Parent
416 }
417
418 fn availability(&self) -> &Availability {
419 &self.availability
420 }
421}
422
423#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
424#[derive(FidlDecl, UseDeclCommon, Debug, Clone, PartialEq, Eq, Hash)]
425#[fidl_decl(fidl_table = "fdecl::UseEventStream", source_path = "name_only")]
426pub struct UseEventStreamDecl {
427 pub source_name: Name,
428 pub source: UseSource,
429 pub scope: Option<Vec<EventScope>>,
430 pub target_path: Path,
431 pub filter: Option<BTreeMap<String, DictionaryValue>>,
432 #[fidl_decl(default)]
433 pub availability: Availability,
434}
435
436#[cfg(fuchsia_api_level_at_least = "HEAD")]
437#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
438#[derive(FidlDecl, Debug, Clone, PartialEq, Eq)]
439#[fidl_decl(fidl_table = "fdecl::UseRunner", source_path = "dictionary")]
440pub struct UseRunnerDecl {
441 pub source: UseSource,
442 pub source_name: Name,
443 #[cfg(fuchsia_api_level_at_least = "25")]
444 #[fidl_decl(default_preserve_none)]
445 pub source_dictionary: RelativePath,
446}
447
448#[cfg(fuchsia_api_level_at_least = "HEAD")]
449impl SourceName for UseRunnerDecl {
450 fn source_name(&self) -> &Name {
451 &self.source_name
452 }
453}
454
455#[cfg(fuchsia_api_level_at_least = "HEAD")]
456impl UseDeclCommon for UseRunnerDecl {
457 fn source(&self) -> &UseSource {
458 &self.source
459 }
460
461 fn availability(&self) -> &Availability {
462 &Availability::Required
463 }
464}
465
466#[cfg(fuchsia_api_level_at_least = "20")]
467#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
468#[derive(FidlDecl, UseDeclCommon, Debug, Clone, PartialEq, Eq)]
469#[fidl_decl(fidl_table = "fdecl::UseConfiguration", source_path = "dictionary")]
470pub struct UseConfigurationDecl {
471 pub source: UseSource,
472 pub source_name: Name,
473 #[cfg(fuchsia_api_level_at_least = "25")]
474 #[fidl_decl(default_preserve_none)]
475 pub source_dictionary: RelativePath,
476 pub target_name: Name,
477 #[fidl_decl(default)]
478 pub availability: Availability,
479 pub type_: ConfigValueType,
480 pub default: Option<ConfigValue>,
481}
482
483#[cfg_attr(
484 feature = "serde",
485 derive(Deserialize, Serialize),
486 serde(tag = "type", rename_all = "snake_case")
487)]
488#[derive(FidlDecl, FromEnum, Debug, Clone, PartialEq, Eq)]
489#[fidl_decl(fidl_union = "fdecl::Offer")]
490pub enum OfferDecl {
491 Service(OfferServiceDecl),
492 Protocol(OfferProtocolDecl),
493 Directory(OfferDirectoryDecl),
494 Storage(OfferStorageDecl),
495 Runner(OfferRunnerDecl),
496 Resolver(OfferResolverDecl),
497 EventStream(OfferEventStreamDecl),
498 #[cfg(fuchsia_api_level_at_least = "25")]
499 Dictionary(OfferDictionaryDecl),
500 #[cfg(fuchsia_api_level_at_least = "20")]
501 Config(OfferConfigurationDecl),
502}
503
504#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
505#[derive(FidlDecl, OfferDeclCommon, Debug, Clone, PartialEq, Eq)]
506#[fidl_decl(fidl_table = "fdecl::OfferEventStream", source_path = "name_only")]
507pub struct OfferEventStreamDecl {
508 pub source: OfferSource,
509 pub scope: Option<Vec<EventScope>>,
510 pub source_name: Name,
511 pub target: OfferTarget,
512 pub target_name: Name,
513 #[fidl_decl(default)]
514 pub availability: Availability,
515}
516
517#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
518#[derive(Debug, Clone, PartialEq, Eq)]
519pub struct NameMapping {
520 pub source_name: Name,
521 pub target_name: Name,
522}
523
524impl NativeIntoFidl<fdecl::NameMapping> for NameMapping {
525 fn native_into_fidl(self) -> fdecl::NameMapping {
526 fdecl::NameMapping {
527 source_name: self.source_name.native_into_fidl(),
528 target_name: self.target_name.native_into_fidl(),
529 }
530 }
531}
532
533impl FidlIntoNative<NameMapping> for fdecl::NameMapping {
534 fn fidl_into_native(self) -> NameMapping {
535 NameMapping {
536 source_name: self.source_name.fidl_into_native(),
537 target_name: self.target_name.fidl_into_native(),
538 }
539 }
540}
541
542#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
543#[derive(FidlDecl, OfferDeclCommon, Debug, Clone, PartialEq, Eq)]
544#[fidl_decl(fidl_table = "fdecl::OfferService", source_path = "dictionary")]
545pub struct OfferServiceDecl {
546 pub source: OfferSource,
547 pub source_name: Name,
548 #[cfg(fuchsia_api_level_at_least = "25")]
549 #[fidl_decl(default_preserve_none)]
550 pub source_dictionary: RelativePath,
551 pub target: OfferTarget,
552 pub target_name: Name,
553 pub source_instance_filter: Option<Vec<Name>>,
554 pub renamed_instances: Option<Vec<NameMapping>>,
555 #[fidl_decl(default)]
556 pub availability: Availability,
557 #[cfg(fuchsia_api_level_at_least = "HEAD")]
558 #[fidl_decl(default)]
559 pub dependency_type: DependencyType,
560}
561
562#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
563#[derive(FidlDecl, OfferDeclCommon, Debug, Clone, PartialEq, Eq)]
564#[fidl_decl(fidl_table = "fdecl::OfferProtocol", source_path = "dictionary")]
565pub struct OfferProtocolDecl {
566 pub source: OfferSource,
567 pub source_name: Name,
568 #[cfg(fuchsia_api_level_at_least = "25")]
569 #[fidl_decl(default_preserve_none)]
570 pub source_dictionary: RelativePath,
571 pub target: OfferTarget,
572 pub target_name: Name,
573 pub dependency_type: DependencyType,
574 #[fidl_decl(default)]
575 pub availability: Availability,
576}
577
578#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
579#[derive(FidlDecl, OfferDeclCommon, Debug, Clone, PartialEq, Eq)]
580#[fidl_decl(fidl_table = "fdecl::OfferDirectory", source_path = "dictionary")]
581pub struct OfferDirectoryDecl {
582 pub source: OfferSource,
583 pub source_name: Name,
584 #[cfg(fuchsia_api_level_at_least = "25")]
585 #[fidl_decl(default_preserve_none)]
586 pub source_dictionary: RelativePath,
587 pub target: OfferTarget,
588 pub target_name: Name,
589 pub dependency_type: DependencyType,
590
591 #[cfg_attr(
592 feature = "serde",
593 serde(
594 deserialize_with = "serde_ext::deserialize_opt_fio_operations",
595 serialize_with = "serde_ext::serialize_opt_fio_operations"
596 )
597 )]
598 pub rights: Option<fio::Operations>,
599
600 #[fidl_decl(default_preserve_none)]
601 pub subdir: RelativePath,
602 #[fidl_decl(default)]
603 pub availability: Availability,
604}
605
606#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
607#[derive(FidlDecl, OfferDeclCommon, Debug, Clone, PartialEq, Eq)]
608#[fidl_decl(fidl_table = "fdecl::OfferStorage", source_path = "name_only")]
609pub struct OfferStorageDecl {
610 pub source: OfferSource,
611 pub source_name: Name,
612 pub target: OfferTarget,
613 pub target_name: Name,
614 #[fidl_decl(default)]
615 pub availability: Availability,
616}
617
618#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
619#[derive(FidlDecl, Debug, Clone, PartialEq, Eq)]
620#[fidl_decl(fidl_table = "fdecl::OfferRunner", source_path = "dictionary")]
621pub struct OfferRunnerDecl {
622 pub source: OfferSource,
623 pub source_name: Name,
624 #[cfg(fuchsia_api_level_at_least = "25")]
625 #[fidl_decl(default_preserve_none)]
626 pub source_dictionary: RelativePath,
627 pub target: OfferTarget,
628 pub target_name: Name,
629}
630
631#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
632#[derive(FidlDecl, OfferDeclCommonNoAvailability, Debug, Clone, PartialEq, Eq)]
633#[fidl_decl(fidl_table = "fdecl::OfferResolver", source_path = "dictionary")]
634pub struct OfferResolverDecl {
635 pub source: OfferSource,
636 pub source_name: Name,
637 #[cfg(fuchsia_api_level_at_least = "25")]
638 #[fidl_decl(default_preserve_none)]
639 pub source_dictionary: RelativePath,
640 pub target: OfferTarget,
641 pub target_name: Name,
642}
643
644#[cfg(fuchsia_api_level_at_least = "25")]
645#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
646#[derive(FidlDecl, OfferDeclCommon, Debug, Clone, PartialEq, Eq)]
647#[fidl_decl(fidl_table = "fdecl::OfferDictionary", source_path = "dictionary")]
648pub struct OfferDictionaryDecl {
649 pub source: OfferSource,
650 pub source_name: Name,
651 #[cfg(fuchsia_api_level_at_least = "25")]
652 #[fidl_decl(default_preserve_none)]
653 pub source_dictionary: RelativePath,
654 pub target: OfferTarget,
655 pub target_name: Name,
656 pub dependency_type: DependencyType,
657 #[fidl_decl(default)]
658 pub availability: Availability,
659}
660
661#[cfg(fuchsia_api_level_at_least = "20")]
662#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
663#[derive(FidlDecl, OfferDeclCommon, Debug, Clone, PartialEq, Eq)]
664#[fidl_decl(fidl_table = "fdecl::OfferConfiguration", source_path = "dictionary")]
665pub struct OfferConfigurationDecl {
666 pub source: OfferSource,
667 pub source_name: Name,
668 #[cfg(fuchsia_api_level_at_least = "25")]
669 #[fidl_decl(default_preserve_none)]
670 pub source_dictionary: RelativePath,
671 pub target: OfferTarget,
672 pub target_name: Name,
673 #[fidl_decl(default)]
674 pub availability: Availability,
675}
676
677impl SourceName for OfferDecl {
678 fn source_name(&self) -> &Name {
679 match &self {
680 OfferDecl::Service(o) => o.source_name(),
681 OfferDecl::Protocol(o) => o.source_name(),
682 OfferDecl::Directory(o) => o.source_name(),
683 OfferDecl::Storage(o) => o.source_name(),
684 OfferDecl::Runner(o) => o.source_name(),
685 OfferDecl::Resolver(o) => o.source_name(),
686 OfferDecl::EventStream(o) => o.source_name(),
687 #[cfg(fuchsia_api_level_at_least = "25")]
688 OfferDecl::Dictionary(o) => o.source_name(),
689 #[cfg(fuchsia_api_level_at_least = "20")]
690 OfferDecl::Config(o) => o.source_name(),
691 }
692 }
693}
694
695impl SourcePath for OfferDecl {
696 fn source_path(&self) -> BorrowedSeparatedPath<'_> {
697 match &self {
698 OfferDecl::Service(o) => o.source_path(),
699 OfferDecl::Protocol(o) => o.source_path(),
700 OfferDecl::Directory(o) => o.source_path(),
701 OfferDecl::Storage(o) => o.source_path(),
702 OfferDecl::Runner(o) => o.source_path(),
703 OfferDecl::Resolver(o) => o.source_path(),
704 OfferDecl::EventStream(o) => o.source_path(),
705 #[cfg(fuchsia_api_level_at_least = "25")]
706 OfferDecl::Dictionary(o) => o.source_path(),
707 #[cfg(fuchsia_api_level_at_least = "20")]
708 OfferDecl::Config(o) => o.source_path(),
709 }
710 }
711}
712
713impl UseDeclCommon for UseDecl {
714 fn source(&self) -> &UseSource {
715 match &self {
716 UseDecl::Service(u) => u.source(),
717 UseDecl::Protocol(u) => u.source(),
718 UseDecl::Directory(u) => u.source(),
719 UseDecl::Storage(u) => u.source(),
720 UseDecl::EventStream(u) => u.source(),
721 #[cfg(fuchsia_api_level_at_least = "HEAD")]
722 UseDecl::Runner(u) => u.source(),
723 #[cfg(fuchsia_api_level_at_least = "20")]
724 UseDecl::Config(u) => u.source(),
725 }
726 }
727
728 fn availability(&self) -> &Availability {
729 match &self {
730 UseDecl::Service(u) => u.availability(),
731 UseDecl::Protocol(u) => u.availability(),
732 UseDecl::Directory(u) => u.availability(),
733 UseDecl::Storage(u) => u.availability(),
734 UseDecl::EventStream(u) => u.availability(),
735 #[cfg(fuchsia_api_level_at_least = "HEAD")]
736 UseDecl::Runner(u) => u.availability(),
737 #[cfg(fuchsia_api_level_at_least = "20")]
738 UseDecl::Config(u) => u.availability(),
739 }
740 }
741}
742
743impl OfferDeclCommon for OfferDecl {
744 fn target_name(&self) -> &Name {
745 match &self {
746 OfferDecl::Service(o) => o.target_name(),
747 OfferDecl::Protocol(o) => o.target_name(),
748 OfferDecl::Directory(o) => o.target_name(),
749 OfferDecl::Storage(o) => o.target_name(),
750 OfferDecl::Runner(o) => o.target_name(),
751 OfferDecl::Resolver(o) => o.target_name(),
752 OfferDecl::EventStream(o) => o.target_name(),
753 #[cfg(fuchsia_api_level_at_least = "25")]
754 OfferDecl::Dictionary(o) => o.target_name(),
755 #[cfg(fuchsia_api_level_at_least = "20")]
756 OfferDecl::Config(o) => o.target_name(),
757 }
758 }
759
760 fn target(&self) -> &OfferTarget {
761 match &self {
762 OfferDecl::Service(o) => o.target(),
763 OfferDecl::Protocol(o) => o.target(),
764 OfferDecl::Directory(o) => o.target(),
765 OfferDecl::Storage(o) => o.target(),
766 OfferDecl::Runner(o) => o.target(),
767 OfferDecl::Resolver(o) => o.target(),
768 OfferDecl::EventStream(o) => o.target(),
769 #[cfg(fuchsia_api_level_at_least = "25")]
770 OfferDecl::Dictionary(o) => o.target(),
771 #[cfg(fuchsia_api_level_at_least = "20")]
772 OfferDecl::Config(o) => o.target(),
773 }
774 }
775
776 fn source(&self) -> &OfferSource {
777 match &self {
778 OfferDecl::Service(o) => o.source(),
779 OfferDecl::Protocol(o) => o.source(),
780 OfferDecl::Directory(o) => o.source(),
781 OfferDecl::Storage(o) => o.source(),
782 OfferDecl::Runner(o) => o.source(),
783 OfferDecl::Resolver(o) => o.source(),
784 OfferDecl::EventStream(o) => o.source(),
785 #[cfg(fuchsia_api_level_at_least = "25")]
786 OfferDecl::Dictionary(o) => o.source(),
787 #[cfg(fuchsia_api_level_at_least = "20")]
788 OfferDecl::Config(o) => o.source(),
789 }
790 }
791
792 fn availability(&self) -> &Availability {
793 match &self {
794 OfferDecl::Service(o) => o.availability(),
795 OfferDecl::Protocol(o) => o.availability(),
796 OfferDecl::Directory(o) => o.availability(),
797 OfferDecl::Storage(o) => o.availability(),
798 OfferDecl::Runner(o) => o.availability(),
799 OfferDecl::Resolver(o) => o.availability(),
800 OfferDecl::EventStream(o) => o.availability(),
801 #[cfg(fuchsia_api_level_at_least = "25")]
802 OfferDecl::Dictionary(o) => o.availability(),
803 #[cfg(fuchsia_api_level_at_least = "20")]
804 OfferDecl::Config(o) => o.availability(),
805 }
806 }
807}
808
809impl SourceName for OfferRunnerDecl {
810 fn source_name(&self) -> &Name {
811 &self.source_name
812 }
813}
814
815impl OfferDeclCommon for OfferRunnerDecl {
816 fn target_name(&self) -> &Name {
817 &self.target_name
818 }
819
820 fn target(&self) -> &OfferTarget {
821 &self.target
822 }
823
824 fn source(&self) -> &OfferSource {
825 &self.source
826 }
827
828 fn availability(&self) -> &Availability {
829 &Availability::Required
830 }
831}
832
833#[cfg_attr(
834 feature = "serde",
835 derive(Deserialize, Serialize),
836 serde(tag = "type", rename_all = "snake_case")
837)]
838#[derive(FidlDecl, FromEnum, Debug, Clone, PartialEq, Eq)]
839#[fidl_decl(fidl_union = "fdecl::Expose")]
840pub enum ExposeDecl {
841 Service(ExposeServiceDecl),
842 Protocol(ExposeProtocolDecl),
843 Directory(ExposeDirectoryDecl),
844 Runner(ExposeRunnerDecl),
845 Resolver(ExposeResolverDecl),
846 #[cfg(fuchsia_api_level_at_least = "25")]
847 Dictionary(ExposeDictionaryDecl),
848 #[cfg(fuchsia_api_level_at_least = "20")]
849 Config(ExposeConfigurationDecl),
850}
851
852impl SourceName for ExposeDecl {
853 fn source_name(&self) -> &Name {
854 match self {
855 Self::Service(e) => e.source_name(),
856 Self::Protocol(e) => e.source_name(),
857 Self::Directory(e) => e.source_name(),
858 Self::Runner(e) => e.source_name(),
859 Self::Resolver(e) => e.source_name(),
860 #[cfg(fuchsia_api_level_at_least = "25")]
861 Self::Dictionary(e) => e.source_name(),
862 #[cfg(fuchsia_api_level_at_least = "20")]
863 Self::Config(e) => e.source_name(),
864 }
865 }
866}
867
868impl SourcePath for ExposeDecl {
869 fn source_path(&self) -> BorrowedSeparatedPath<'_> {
870 match self {
871 Self::Service(e) => e.source_path(),
872 Self::Protocol(e) => e.source_path(),
873 Self::Directory(e) => e.source_path(),
874 Self::Runner(e) => e.source_path(),
875 Self::Resolver(e) => e.source_path(),
876 #[cfg(fuchsia_api_level_at_least = "25")]
877 Self::Dictionary(e) => e.source_path(),
878 #[cfg(fuchsia_api_level_at_least = "20")]
879 Self::Config(e) => e.source_path(),
880 }
881 }
882}
883
884impl ExposeDeclCommon for ExposeDecl {
885 fn source(&self) -> &ExposeSource {
886 match self {
887 Self::Service(e) => e.source(),
888 Self::Protocol(e) => e.source(),
889 Self::Directory(e) => e.source(),
890 Self::Runner(e) => e.source(),
891 Self::Resolver(e) => e.source(),
892 #[cfg(fuchsia_api_level_at_least = "25")]
893 Self::Dictionary(e) => e.source(),
894 #[cfg(fuchsia_api_level_at_least = "20")]
895 Self::Config(e) => e.source(),
896 }
897 }
898
899 fn target(&self) -> &ExposeTarget {
900 match self {
901 Self::Service(e) => e.target(),
902 Self::Protocol(e) => e.target(),
903 Self::Directory(e) => e.target(),
904 Self::Runner(e) => e.target(),
905 Self::Resolver(e) => e.target(),
906 #[cfg(fuchsia_api_level_at_least = "25")]
907 Self::Dictionary(e) => e.target(),
908 #[cfg(fuchsia_api_level_at_least = "20")]
909 Self::Config(e) => e.target(),
910 }
911 }
912
913 fn target_name(&self) -> &Name {
914 match self {
915 Self::Service(e) => e.target_name(),
916 Self::Protocol(e) => e.target_name(),
917 Self::Directory(e) => e.target_name(),
918 Self::Runner(e) => e.target_name(),
919 Self::Resolver(e) => e.target_name(),
920 #[cfg(fuchsia_api_level_at_least = "25")]
921 Self::Dictionary(e) => e.target_name(),
922 #[cfg(fuchsia_api_level_at_least = "20")]
923 Self::Config(e) => e.target_name(),
924 }
925 }
926
927 fn availability(&self) -> &Availability {
928 match self {
929 Self::Service(e) => e.availability(),
930 Self::Protocol(e) => e.availability(),
931 Self::Directory(e) => e.availability(),
932 Self::Runner(e) => e.availability(),
933 Self::Resolver(e) => e.availability(),
934 #[cfg(fuchsia_api_level_at_least = "25")]
935 Self::Dictionary(e) => e.availability(),
936 #[cfg(fuchsia_api_level_at_least = "20")]
937 Self::Config(e) => e.availability(),
938 }
939 }
940}
941
942#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
943#[derive(FidlDecl, ExposeDeclCommon, Debug, Clone, PartialEq, Eq)]
944#[fidl_decl(fidl_table = "fdecl::ExposeService", source_path = "dictionary")]
945pub struct ExposeServiceDecl {
946 pub source: ExposeSource,
947 pub source_name: Name,
948 #[cfg(fuchsia_api_level_at_least = "25")]
949 #[fidl_decl(default_preserve_none)]
950 pub source_dictionary: RelativePath,
951 pub target: ExposeTarget,
952 pub target_name: Name,
953 #[fidl_decl(default)]
954 pub availability: Availability,
955}
956
957#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
958#[derive(FidlDecl, ExposeDeclCommon, Debug, Clone, PartialEq, Eq)]
959#[fidl_decl(fidl_table = "fdecl::ExposeProtocol", source_path = "dictionary")]
960pub struct ExposeProtocolDecl {
961 pub source: ExposeSource,
962 pub source_name: Name,
963 #[cfg(fuchsia_api_level_at_least = "25")]
964 #[fidl_decl(default_preserve_none)]
965 pub source_dictionary: RelativePath,
966 pub target: ExposeTarget,
967 pub target_name: Name,
968 #[fidl_decl(default)]
969 pub availability: Availability,
970}
971
972#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
973#[derive(FidlDecl, ExposeDeclCommon, Debug, Clone, PartialEq, Eq)]
974#[fidl_decl(fidl_table = "fdecl::ExposeDirectory", source_path = "dictionary")]
975pub struct ExposeDirectoryDecl {
976 pub source: ExposeSource,
977 pub source_name: Name,
978 #[cfg(fuchsia_api_level_at_least = "25")]
979 #[fidl_decl(default_preserve_none)]
980 pub source_dictionary: RelativePath,
981 pub target: ExposeTarget,
982 pub target_name: Name,
983
984 #[cfg_attr(
985 feature = "serde",
986 serde(
987 deserialize_with = "serde_ext::deserialize_opt_fio_operations",
988 serialize_with = "serde_ext::serialize_opt_fio_operations"
989 )
990 )]
991 pub rights: Option<fio::Operations>,
992
993 #[fidl_decl(default_preserve_none)]
994 pub subdir: RelativePath,
995
996 #[fidl_decl(default)]
997 pub availability: Availability,
998}
999
1000#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
1001#[derive(FidlDecl, ExposeDeclCommonAlwaysRequired, Debug, Clone, PartialEq, Eq)]
1002#[fidl_decl(fidl_table = "fdecl::ExposeRunner", source_path = "dictionary")]
1003pub struct ExposeRunnerDecl {
1004 pub source: ExposeSource,
1005 pub source_name: Name,
1006 #[cfg(fuchsia_api_level_at_least = "25")]
1007 #[fidl_decl(default_preserve_none)]
1008 pub source_dictionary: RelativePath,
1009 pub target: ExposeTarget,
1010 pub target_name: Name,
1011}
1012
1013#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
1014#[derive(FidlDecl, ExposeDeclCommonAlwaysRequired, Debug, Clone, PartialEq, Eq)]
1015#[fidl_decl(fidl_table = "fdecl::ExposeResolver", source_path = "dictionary")]
1016pub struct ExposeResolverDecl {
1017 pub source: ExposeSource,
1018 pub source_name: Name,
1019 #[cfg(fuchsia_api_level_at_least = "25")]
1020 #[fidl_decl(default_preserve_none)]
1021 pub source_dictionary: RelativePath,
1022 pub target: ExposeTarget,
1023 pub target_name: Name,
1024}
1025
1026#[cfg(fuchsia_api_level_at_least = "25")]
1027#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
1028#[derive(FidlDecl, ExposeDeclCommon, Debug, Clone, PartialEq, Eq)]
1029#[fidl_decl(fidl_table = "fdecl::ExposeDictionary", source_path = "dictionary")]
1030pub struct ExposeDictionaryDecl {
1031 pub source: ExposeSource,
1032 pub source_name: Name,
1033 #[cfg(fuchsia_api_level_at_least = "25")]
1034 #[fidl_decl(default_preserve_none)]
1035 pub source_dictionary: RelativePath,
1036 pub target: ExposeTarget,
1037 pub target_name: Name,
1038 #[fidl_decl(default)]
1039 pub availability: Availability,
1040}
1041
1042#[cfg(fuchsia_api_level_at_least = "20")]
1043#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
1044#[derive(FidlDecl, ExposeDeclCommon, Debug, Clone, PartialEq, Eq)]
1045#[fidl_decl(fidl_table = "fdecl::ExposeConfiguration", source_path = "name_only")]
1046pub struct ExposeConfigurationDecl {
1047 pub source: ExposeSource,
1048 pub source_name: Name,
1049 pub target: ExposeTarget,
1050 pub target_name: Name,
1051 #[cfg(fuchsia_api_level_at_least = "25")]
1052 #[fidl_decl(default_preserve_none)]
1053 pub source_dictionary: RelativePath,
1054 #[fidl_decl(default)]
1055 pub availability: Availability,
1056}
1057
1058#[cfg_attr(
1059 feature = "serde",
1060 derive(Deserialize, Serialize),
1061 serde(tag = "type", rename_all = "snake_case")
1062)]
1063#[derive(FidlDecl, FromEnum, Debug, Clone, PartialEq, Eq)]
1064#[fidl_decl(fidl_union = "fdecl::Capability")]
1065pub enum CapabilityDecl {
1066 Service(ServiceDecl),
1067 Protocol(ProtocolDecl),
1068 Directory(DirectoryDecl),
1069 Storage(StorageDecl),
1070 Runner(RunnerDecl),
1071 Resolver(ResolverDecl),
1072 EventStream(EventStreamDecl),
1073 #[cfg(fuchsia_api_level_at_least = "25")]
1074 Dictionary(DictionaryDecl),
1075 #[cfg(fuchsia_api_level_at_least = "20")]
1076 Config(ConfigurationDecl),
1077}
1078
1079#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
1080#[derive(FidlDecl, Debug, Clone, PartialEq, Eq)]
1081#[fidl_decl(fidl_table = "fdecl::Service")]
1082pub struct ServiceDecl {
1083 pub name: Name,
1084 pub source_path: Option<Path>,
1085}
1086
1087#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
1088#[derive(FidlDecl, Debug, Clone, PartialEq, Eq)]
1089#[fidl_decl(fidl_table = "fdecl::Protocol")]
1090pub struct ProtocolDecl {
1091 pub name: Name,
1092 pub source_path: Option<Path>,
1093 #[fidl_decl(default)]
1094 #[cfg(fuchsia_api_level_at_least = "HEAD")]
1095 pub delivery: DeliveryType,
1096}
1097
1098#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
1099#[derive(FidlDecl, Debug, Clone, PartialEq, Eq)]
1100#[fidl_decl(fidl_table = "fdecl::Directory")]
1101pub struct DirectoryDecl {
1102 pub name: Name,
1103 pub source_path: Option<Path>,
1104
1105 #[cfg_attr(
1106 feature = "serde",
1107 serde(
1108 deserialize_with = "serde_ext::deserialize_fio_operations",
1109 serialize_with = "serde_ext::serialize_fio_operations"
1110 )
1111 )]
1112 pub rights: fio::Operations,
1113}
1114
1115#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
1116#[derive(FidlDecl, Debug, Clone, PartialEq, Eq)]
1117#[fidl_decl(fidl_table = "fdecl::Storage")]
1118pub struct StorageDecl {
1119 pub name: Name,
1120 pub source: StorageDirectorySource,
1121 pub backing_dir: Name,
1122 #[fidl_decl(default_preserve_none)]
1123 pub subdir: RelativePath,
1124 #[cfg_attr(feature = "serde", serde(with = "serde_ext::StorageId"))]
1125 pub storage_id: fdecl::StorageId,
1126}
1127
1128#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
1129#[derive(FidlDecl, Debug, Clone, PartialEq, Eq)]
1130#[fidl_decl(fidl_table = "fdecl::Runner")]
1131pub struct RunnerDecl {
1132 pub name: Name,
1133 pub source_path: Option<Path>,
1134}
1135
1136#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
1137#[derive(FidlDecl, Debug, Clone, PartialEq, Eq)]
1138#[fidl_decl(fidl_table = "fdecl::Resolver")]
1139pub struct ResolverDecl {
1140 pub name: Name,
1141 pub source_path: Option<Path>,
1142}
1143
1144#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
1145#[derive(FidlDecl, Debug, Clone, PartialEq, Eq)]
1146#[fidl_decl(fidl_table = "fdecl::EventStream")]
1147pub struct EventStreamDecl {
1148 pub name: Name,
1149}
1150
1151#[cfg(fuchsia_api_level_at_least = "25")]
1152#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
1153#[derive(FidlDecl, Debug, Clone, PartialEq, Eq)]
1154#[fidl_decl(fidl_table = "fdecl::Dictionary")]
1155pub struct DictionaryDecl {
1156 pub name: Name,
1157 pub source_path: Option<Path>,
1158}
1159
1160#[cfg(fuchsia_api_level_at_least = "20")]
1161#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
1162#[derive(FidlDecl, Debug, Clone, PartialEq, Eq)]
1163#[fidl_decl(fidl_table = "fdecl::Configuration")]
1164pub struct ConfigurationDecl {
1165 pub name: Name,
1166 pub value: ConfigValue,
1167}
1168
1169impl CapabilityDecl {
1170 pub fn name(&self) -> &Name {
1171 match self {
1172 CapabilityDecl::Directory(decl) => &decl.name,
1173 CapabilityDecl::Protocol(decl) => &decl.name,
1174 CapabilityDecl::Resolver(decl) => &decl.name,
1175 CapabilityDecl::Runner(decl) => &decl.name,
1176 CapabilityDecl::Service(decl) => &decl.name,
1177 CapabilityDecl::Storage(decl) => &decl.name,
1178 CapabilityDecl::EventStream(decl) => &decl.name,
1179 #[cfg(fuchsia_api_level_at_least = "25")]
1180 CapabilityDecl::Dictionary(decl) => &decl.name,
1181 #[cfg(fuchsia_api_level_at_least = "20")]
1182 CapabilityDecl::Config(decl) => &decl.name,
1183 }
1184 }
1185
1186 pub fn path(&self) -> Option<&Path> {
1187 match self {
1188 CapabilityDecl::Directory(decl) => decl.source_path.as_ref(),
1189 CapabilityDecl::Protocol(decl) => decl.source_path.as_ref(),
1190 CapabilityDecl::Resolver(decl) => decl.source_path.as_ref(),
1191 CapabilityDecl::Runner(decl) => decl.source_path.as_ref(),
1192 CapabilityDecl::Service(decl) => decl.source_path.as_ref(),
1193 CapabilityDecl::Storage(_) => None,
1194 CapabilityDecl::EventStream(_) => None,
1195 #[cfg(fuchsia_api_level_at_least = "25")]
1196 CapabilityDecl::Dictionary(_) => None,
1197 #[cfg(fuchsia_api_level_at_least = "20")]
1198 CapabilityDecl::Config(_) => None,
1199 }
1200 }
1201}
1202
1203#[derive(FidlDecl, Debug, Clone, PartialEq, Eq)]
1204#[fidl_decl(fidl_table = "fdecl::Child")]
1205pub struct ChildDecl {
1206 pub name: LongName,
1207 pub url: Url,
1208 pub startup: fdecl::StartupMode,
1209 pub on_terminate: Option<fdecl::OnTerminate>,
1210 pub environment: Option<Name>,
1211 pub config_overrides: Option<Vec<ConfigOverride>>,
1212}
1213
1214#[cfg_attr(feature = "serde", derive(Deserialize, Serialize), serde(rename_all = "snake_case"))]
1215#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1216pub struct ChildRef {
1217 pub name: LongName,
1218 pub collection: Option<Name>,
1219}
1220
1221impl std::fmt::Display for ChildRef {
1222 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1223 if let Some(collection) = &self.collection {
1224 write!(f, "{}:{}", collection, self.name)
1225 } else {
1226 write!(f, "{}", self.name)
1227 }
1228 }
1229}
1230
1231impl FidlIntoNative<ChildRef> for fdecl::ChildRef {
1232 fn fidl_into_native(self) -> ChildRef {
1233 ChildRef {
1235 name: self.name.parse().unwrap(),
1236 collection: self.collection.map(|c| c.parse().unwrap()),
1237 }
1238 }
1239}
1240
1241impl NativeIntoFidl<fdecl::ChildRef> for ChildRef {
1242 fn native_into_fidl(self) -> fdecl::ChildRef {
1243 fdecl::ChildRef {
1244 name: self.name.to_string(),
1245 collection: self.collection.map(|c| c.to_string()),
1246 }
1247 }
1248}
1249
1250#[derive(FidlDecl, Debug, Clone, PartialEq, Eq)]
1251#[fidl_decl(fidl_table = "fdecl::Collection")]
1252pub struct CollectionDecl {
1253 pub name: Name,
1254 pub durability: fdecl::Durability,
1255 pub environment: Option<Name>,
1256
1257 #[fidl_decl(default)]
1258 pub allowed_offers: AllowedOffers,
1259 #[fidl_decl(default)]
1260 pub allow_long_names: bool,
1261
1262 pub persistent_storage: Option<bool>,
1263}
1264
1265#[derive(FidlDecl, Debug, Clone, PartialEq, Eq)]
1266#[fidl_decl(fidl_table = "fdecl::Environment")]
1267pub struct EnvironmentDecl {
1268 pub name: Name,
1269 pub extends: fdecl::EnvironmentExtends,
1270 pub runners: Vec<RunnerRegistration>,
1271 pub resolvers: Vec<ResolverRegistration>,
1272 pub debug_capabilities: Vec<DebugRegistration>,
1273 pub stop_timeout_ms: Option<u32>,
1274}
1275
1276#[derive(FidlDecl, Debug, Clone, PartialEq, Eq)]
1277#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
1278#[fidl_decl(fidl_table = "fdecl::ConfigOverride")]
1279pub struct ConfigOverride {
1280 pub key: String,
1281 pub value: ConfigValue,
1282}
1283
1284#[derive(FidlDecl, Debug, Clone, PartialEq, Eq)]
1285#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
1286#[fidl_decl(fidl_table = "fdecl::ConfigSchema")]
1287pub struct ConfigDecl {
1288 pub fields: Vec<ConfigField>,
1289 pub checksum: ConfigChecksum,
1290 pub value_source: ConfigValueSource,
1291}
1292
1293#[derive(FidlDecl, Debug, Clone, PartialEq, Eq)]
1294#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
1295#[fidl_decl(fidl_union = "fdecl::ConfigChecksum")]
1296pub enum ConfigChecksum {
1297 Sha256([u8; 32]),
1298}
1299
1300#[cfg(fuchsia_api_level_at_least = "HEAD")]
1301#[derive(FidlDecl, Debug, Default, Clone, PartialEq, Eq)]
1302#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
1303#[fidl_decl(fidl_table = "fdecl::ConfigSourceCapabilities")]
1304pub struct ConfigSourceCapabilities {}
1305
1306#[derive(FidlDecl, Debug, Clone, PartialEq, Eq)]
1307#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
1308#[fidl_decl(fidl_union = "fdecl::ConfigValueSource")]
1309pub enum ConfigValueSource {
1310 PackagePath(String),
1311 #[cfg(fuchsia_api_level_at_least = "HEAD")]
1312 Capabilities(ConfigSourceCapabilities),
1313}
1314
1315#[derive(FidlDecl, Debug, Clone, PartialEq, Eq)]
1316#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
1317#[fidl_decl(fidl_table = "fdecl::ConfigField")]
1318pub struct ConfigField {
1319 pub key: String,
1320 pub type_: ConfigValueType,
1321
1322 #[fidl_decl(default)]
1324 pub mutability: ConfigMutability,
1325}
1326
1327#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
1328#[derive(Debug, Clone, PartialEq, Eq)]
1329pub enum ConfigNestedValueType {
1330 Bool,
1331 Uint8,
1332 Int8,
1333 Uint16,
1334 Int16,
1335 Uint32,
1336 Int32,
1337 Uint64,
1338 Int64,
1339 String { max_size: u32 },
1340}
1341
1342#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
1343#[derive(Debug, Clone, PartialEq, Eq)]
1344pub enum ConfigValueType {
1345 Bool,
1346 Uint8,
1347 Int8,
1348 Uint16,
1349 Int16,
1350 Uint32,
1351 Int32,
1352 Uint64,
1353 Int64,
1354 String { max_size: u32 },
1355 Vector { nested_type: ConfigNestedValueType, max_count: u32 },
1356}
1357
1358impl ConfigValueType {
1359 pub fn get_max_size(&self) -> Option<u32> {
1360 match self {
1361 ConfigValueType::String { max_size } => Some(*max_size),
1362 ConfigValueType::Bool
1363 | ConfigValueType::Uint8
1364 | ConfigValueType::Int8
1365 | ConfigValueType::Uint16
1366 | ConfigValueType::Int16
1367 | ConfigValueType::Uint32
1368 | ConfigValueType::Int32
1369 | ConfigValueType::Uint64
1370 | ConfigValueType::Int64
1371 | ConfigValueType::Vector { .. } => None,
1372 }
1373 }
1374
1375 pub fn get_nested_type(&self) -> Option<ConfigNestedValueType> {
1376 match self {
1377 ConfigValueType::Vector { nested_type, .. } => Some(nested_type.clone()),
1378 ConfigValueType::Bool
1379 | ConfigValueType::Uint8
1380 | ConfigValueType::Int8
1381 | ConfigValueType::Uint16
1382 | ConfigValueType::Int16
1383 | ConfigValueType::Uint32
1384 | ConfigValueType::Int32
1385 | ConfigValueType::Uint64
1386 | ConfigValueType::Int64
1387 | ConfigValueType::String { .. } => None,
1388 }
1389 }
1390
1391 pub fn get_max_count(&self) -> Option<u32> {
1392 match self {
1393 ConfigValueType::Vector { max_count, .. } => Some(*max_count),
1394 ConfigValueType::Bool
1395 | ConfigValueType::Uint8
1396 | ConfigValueType::Int8
1397 | ConfigValueType::Uint16
1398 | ConfigValueType::Int16
1399 | ConfigValueType::Uint32
1400 | ConfigValueType::Int32
1401 | ConfigValueType::Uint64
1402 | ConfigValueType::Int64
1403 | ConfigValueType::String { .. } => None,
1404 }
1405 }
1406}
1407
1408impl FidlIntoNative<ConfigNestedValueType> for fdecl::ConfigType {
1409 fn fidl_into_native(mut self) -> ConfigNestedValueType {
1410 match self.layout {
1411 fdecl::ConfigTypeLayout::Bool => ConfigNestedValueType::Bool,
1412 fdecl::ConfigTypeLayout::Uint8 => ConfigNestedValueType::Uint8,
1413 fdecl::ConfigTypeLayout::Uint16 => ConfigNestedValueType::Uint16,
1414 fdecl::ConfigTypeLayout::Uint32 => ConfigNestedValueType::Uint32,
1415 fdecl::ConfigTypeLayout::Uint64 => ConfigNestedValueType::Uint64,
1416 fdecl::ConfigTypeLayout::Int8 => ConfigNestedValueType::Int8,
1417 fdecl::ConfigTypeLayout::Int16 => ConfigNestedValueType::Int16,
1418 fdecl::ConfigTypeLayout::Int32 => ConfigNestedValueType::Int32,
1419 fdecl::ConfigTypeLayout::Int64 => ConfigNestedValueType::Int64,
1420 fdecl::ConfigTypeLayout::String => {
1421 let max_size =
1422 if let fdecl::LayoutConstraint::MaxSize(s) = self.constraints.remove(0) {
1423 s
1424 } else {
1425 panic!("Unexpected constraint on String layout type for config field");
1426 };
1427 ConfigNestedValueType::String { max_size }
1428 }
1429 fdecl::ConfigTypeLayout::Vector => {
1430 panic!("Nested vectors are not supported in structured config")
1431 }
1432 fdecl::ConfigTypeLayoutUnknown!() => panic!("Unknown layout type for config field"),
1433 }
1434 }
1435}
1436
1437impl NativeIntoFidl<fdecl::ConfigType> for ConfigNestedValueType {
1438 fn native_into_fidl(self) -> fdecl::ConfigType {
1439 let layout = match self {
1440 ConfigNestedValueType::Bool => fdecl::ConfigTypeLayout::Bool,
1441 ConfigNestedValueType::Uint8 => fdecl::ConfigTypeLayout::Uint8,
1442 ConfigNestedValueType::Uint16 => fdecl::ConfigTypeLayout::Uint16,
1443 ConfigNestedValueType::Uint32 => fdecl::ConfigTypeLayout::Uint32,
1444 ConfigNestedValueType::Uint64 => fdecl::ConfigTypeLayout::Uint64,
1445 ConfigNestedValueType::Int8 => fdecl::ConfigTypeLayout::Int8,
1446 ConfigNestedValueType::Int16 => fdecl::ConfigTypeLayout::Int16,
1447 ConfigNestedValueType::Int32 => fdecl::ConfigTypeLayout::Int32,
1448 ConfigNestedValueType::Int64 => fdecl::ConfigTypeLayout::Int64,
1449 ConfigNestedValueType::String { .. } => fdecl::ConfigTypeLayout::String,
1450 };
1451 let constraints = match self {
1452 ConfigNestedValueType::String { max_size } => {
1453 vec![fdecl::LayoutConstraint::MaxSize(max_size)]
1454 }
1455 _ => vec![],
1456 };
1457 fdecl::ConfigType { layout, constraints, parameters: Some(vec![]) }
1458 }
1459}
1460
1461impl FidlIntoNative<ConfigValueType> for fdecl::ConfigType {
1462 fn fidl_into_native(mut self) -> ConfigValueType {
1463 match self.layout {
1464 fdecl::ConfigTypeLayout::Bool => ConfigValueType::Bool,
1465 fdecl::ConfigTypeLayout::Uint8 => ConfigValueType::Uint8,
1466 fdecl::ConfigTypeLayout::Uint16 => ConfigValueType::Uint16,
1467 fdecl::ConfigTypeLayout::Uint32 => ConfigValueType::Uint32,
1468 fdecl::ConfigTypeLayout::Uint64 => ConfigValueType::Uint64,
1469 fdecl::ConfigTypeLayout::Int8 => ConfigValueType::Int8,
1470 fdecl::ConfigTypeLayout::Int16 => ConfigValueType::Int16,
1471 fdecl::ConfigTypeLayout::Int32 => ConfigValueType::Int32,
1472 fdecl::ConfigTypeLayout::Int64 => ConfigValueType::Int64,
1473 fdecl::ConfigTypeLayout::String => {
1474 let max_size = if let fdecl::LayoutConstraint::MaxSize(s) =
1475 self.constraints.remove(0)
1476 {
1477 s
1478 } else {
1479 panic!("Unexpected constraint on String layout type for config field. Expected MaxSize.");
1480 };
1481 ConfigValueType::String { max_size }
1482 }
1483 fdecl::ConfigTypeLayout::Vector => {
1484 let max_count = if let fdecl::LayoutConstraint::MaxSize(c) =
1485 self.constraints.remove(0)
1486 {
1487 c
1488 } else {
1489 panic!("Unexpected constraint on Vector layout type for config field. Expected MaxSize.");
1490 };
1491 let mut parameters =
1492 self.parameters.expect("Config field must have parameters set");
1493 let nested_type = if let fdecl::LayoutParameter::NestedType(nested_type) =
1494 parameters.remove(0)
1495 {
1496 nested_type.fidl_into_native()
1497 } else {
1498 panic!("Unexpected parameter on Vector layout type for config field. Expected NestedType.");
1499 };
1500 ConfigValueType::Vector { max_count, nested_type }
1501 }
1502 fdecl::ConfigTypeLayoutUnknown!() => panic!("Unknown layout type for config field"),
1503 }
1504 }
1505}
1506
1507impl NativeIntoFidl<fdecl::ConfigType> for ConfigValueType {
1508 fn native_into_fidl(self) -> fdecl::ConfigType {
1509 let layout = match self {
1510 ConfigValueType::Bool => fdecl::ConfigTypeLayout::Bool,
1511 ConfigValueType::Uint8 => fdecl::ConfigTypeLayout::Uint8,
1512 ConfigValueType::Uint16 => fdecl::ConfigTypeLayout::Uint16,
1513 ConfigValueType::Uint32 => fdecl::ConfigTypeLayout::Uint32,
1514 ConfigValueType::Uint64 => fdecl::ConfigTypeLayout::Uint64,
1515 ConfigValueType::Int8 => fdecl::ConfigTypeLayout::Int8,
1516 ConfigValueType::Int16 => fdecl::ConfigTypeLayout::Int16,
1517 ConfigValueType::Int32 => fdecl::ConfigTypeLayout::Int32,
1518 ConfigValueType::Int64 => fdecl::ConfigTypeLayout::Int64,
1519 ConfigValueType::String { .. } => fdecl::ConfigTypeLayout::String,
1520 ConfigValueType::Vector { .. } => fdecl::ConfigTypeLayout::Vector,
1521 };
1522 let (constraints, parameters) = match self {
1523 ConfigValueType::String { max_size } => {
1524 (vec![fdecl::LayoutConstraint::MaxSize(max_size)], vec![])
1525 }
1526 ConfigValueType::Vector { max_count, nested_type } => {
1527 let nested_type = nested_type.native_into_fidl();
1528 (
1529 vec![fdecl::LayoutConstraint::MaxSize(max_count)],
1530 vec![fdecl::LayoutParameter::NestedType(nested_type)],
1531 )
1532 }
1533 _ => (vec![], vec![]),
1534 };
1535 fdecl::ConfigType { layout, constraints, parameters: Some(parameters) }
1536 }
1537}
1538
1539bitflags::bitflags! {
1540 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
1541 pub struct ConfigMutability: u32 {
1544 const PARENT = fdecl::ConfigMutability::PARENT.bits();
1545 }
1546}
1547
1548#[cfg(feature = "serde")]
1549bitflags_serde_legacy::impl_traits!(ConfigMutability);
1550
1551impl NativeIntoFidl<fdecl::ConfigMutability> for ConfigMutability {
1552 fn native_into_fidl(self) -> fdecl::ConfigMutability {
1553 fdecl::ConfigMutability::from_bits_allow_unknown(self.bits())
1554 }
1555}
1556
1557impl FidlIntoNative<ConfigMutability> for fdecl::ConfigMutability {
1558 fn fidl_into_native(self) -> ConfigMutability {
1559 ConfigMutability::from_bits_retain(self.bits())
1560 }
1561}
1562
1563#[derive(FidlDecl, Debug, Clone, PartialEq, Eq)]
1564#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
1565#[fidl_decl(fidl_table = "fdecl::ConfigValuesData")]
1566pub struct ConfigValuesData {
1567 pub values: Vec<ConfigValueSpec>,
1568 pub checksum: ConfigChecksum,
1569}
1570
1571#[derive(FidlDecl, Debug, Clone, PartialEq, Eq)]
1572#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
1573#[fidl_decl(fidl_table = "fdecl::ConfigValueSpec")]
1574pub struct ConfigValueSpec {
1575 pub value: ConfigValue,
1576}
1577
1578#[derive(FromEnum, FidlDecl, Debug, Clone, PartialEq, Eq)]
1579#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
1580#[fidl_decl(fidl_union = "fdecl::ConfigValue")]
1581pub enum ConfigValue {
1582 Single(ConfigSingleValue),
1583 Vector(ConfigVectorValue),
1584}
1585
1586impl ConfigValue {
1587 pub fn ty(&self) -> ConfigValueType {
1589 match self {
1590 Self::Single(sv) => sv.ty(),
1591 Self::Vector(vv) => vv.ty(),
1592 }
1593 }
1594
1595 pub fn matches_type(&self, other: &ConfigValue) -> bool {
1597 match (self, other) {
1598 (ConfigValue::Single(a), ConfigValue::Single(b)) => {
1599 std::mem::discriminant(a) == std::mem::discriminant(b)
1600 }
1601 (ConfigValue::Vector(a), ConfigValue::Vector(b)) => {
1602 std::mem::discriminant(a) == std::mem::discriminant(b)
1603 }
1604 _ => false,
1605 }
1606 }
1607}
1608
1609impl From<&str> for ConfigValue {
1610 fn from(value: &str) -> Self {
1611 ConfigValue::Single(value.to_string().into())
1612 }
1613}
1614
1615impl From<Vec<&str>> for ConfigValue {
1616 fn from(value: Vec<&str>) -> Self {
1617 let value: Vec<_> = value.into_iter().map(|s| s.to_string()).collect();
1618 ConfigValue::Vector(value.into())
1619 }
1620}
1621
1622macro_rules! generate_configvalue_from {
1623 ($name:expr, $type:ty) => {
1624 impl From<$type> for ConfigValue {
1625 fn from(value: $type) -> Self {
1626 $name(value.into())
1627 }
1628 }
1629 };
1630}
1631
1632generate_configvalue_from!(ConfigValue::Single, bool);
1633generate_configvalue_from!(ConfigValue::Single, u8);
1634generate_configvalue_from!(ConfigValue::Single, u16);
1635generate_configvalue_from!(ConfigValue::Single, u32);
1636generate_configvalue_from!(ConfigValue::Single, u64);
1637generate_configvalue_from!(ConfigValue::Single, i8);
1638generate_configvalue_from!(ConfigValue::Single, i16);
1639generate_configvalue_from!(ConfigValue::Single, i32);
1640generate_configvalue_from!(ConfigValue::Single, i64);
1641generate_configvalue_from!(ConfigValue::Single, String);
1642generate_configvalue_from!(ConfigValue::Vector, Vec<bool>);
1643generate_configvalue_from!(ConfigValue::Vector, Vec<u8>);
1644generate_configvalue_from!(ConfigValue::Vector, Vec<u16>);
1645generate_configvalue_from!(ConfigValue::Vector, Vec<u32>);
1646generate_configvalue_from!(ConfigValue::Vector, Vec<u64>);
1647generate_configvalue_from!(ConfigValue::Vector, Vec<i8>);
1648generate_configvalue_from!(ConfigValue::Vector, Vec<i16>);
1649generate_configvalue_from!(ConfigValue::Vector, Vec<i32>);
1650generate_configvalue_from!(ConfigValue::Vector, Vec<i64>);
1651generate_configvalue_from!(ConfigValue::Vector, Vec<String>);
1652
1653impl fmt::Display for ConfigValue {
1654 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1655 match self {
1656 ConfigValue::Single(sv) => sv.fmt(f),
1657 ConfigValue::Vector(lv) => lv.fmt(f),
1658 }
1659 }
1660}
1661
1662#[derive(FromEnum, FidlDecl, Debug, Clone, PartialEq, Eq)]
1663#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
1664#[fidl_decl(fidl_union = "fdecl::ConfigSingleValue")]
1665pub enum ConfigSingleValue {
1666 Bool(bool),
1667 Uint8(u8),
1668 Uint16(u16),
1669 Uint32(u32),
1670 Uint64(u64),
1671 Int8(i8),
1672 Int16(i16),
1673 Int32(i32),
1674 Int64(i64),
1675 String(String),
1676}
1677
1678impl ConfigSingleValue {
1679 fn ty(&self) -> ConfigValueType {
1680 match self {
1681 ConfigSingleValue::Bool(_) => ConfigValueType::Bool,
1682 ConfigSingleValue::Uint8(_) => ConfigValueType::Uint8,
1683 ConfigSingleValue::Uint16(_) => ConfigValueType::Uint16,
1684 ConfigSingleValue::Uint32(_) => ConfigValueType::Uint32,
1685 ConfigSingleValue::Uint64(_) => ConfigValueType::Uint64,
1686 ConfigSingleValue::Int8(_) => ConfigValueType::Int8,
1687 ConfigSingleValue::Int16(_) => ConfigValueType::Int16,
1688 ConfigSingleValue::Int32(_) => ConfigValueType::Int32,
1689 ConfigSingleValue::Int64(_) => ConfigValueType::Int64,
1690 ConfigSingleValue::String(_) => ConfigValueType::String { max_size: std::u32::MAX },
1692 }
1693 }
1694}
1695
1696impl fmt::Display for ConfigSingleValue {
1697 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1698 use ConfigSingleValue::*;
1699 match self {
1700 Bool(v) => write!(f, "{}", v),
1701 Uint8(v) => write!(f, "{}", v),
1702 Uint16(v) => write!(f, "{}", v),
1703 Uint32(v) => write!(f, "{}", v),
1704 Uint64(v) => write!(f, "{}", v),
1705 Int8(v) => write!(f, "{}", v),
1706 Int16(v) => write!(f, "{}", v),
1707 Int32(v) => write!(f, "{}", v),
1708 Int64(v) => write!(f, "{}", v),
1709 String(v) => write!(f, "\"{}\"", v),
1710 }
1711 }
1712}
1713
1714#[derive(FromEnum, FidlDecl, Debug, Clone, PartialEq, Eq)]
1715#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
1716#[fidl_decl(fidl_union = "fdecl::ConfigVectorValue")]
1717pub enum ConfigVectorValue {
1718 BoolVector(Vec<bool>),
1719 Uint8Vector(Vec<u8>),
1720 Uint16Vector(Vec<u16>),
1721 Uint32Vector(Vec<u32>),
1722 Uint64Vector(Vec<u64>),
1723 Int8Vector(Vec<i8>),
1724 Int16Vector(Vec<i16>),
1725 Int32Vector(Vec<i32>),
1726 Int64Vector(Vec<i64>),
1727 StringVector(Vec<String>),
1728}
1729
1730impl ConfigVectorValue {
1731 fn ty(&self) -> ConfigValueType {
1732 match self {
1734 ConfigVectorValue::BoolVector(_) => ConfigValueType::Vector {
1735 nested_type: ConfigNestedValueType::Bool,
1736 max_count: std::u32::MAX,
1737 },
1738 ConfigVectorValue::Uint8Vector(_) => ConfigValueType::Vector {
1739 nested_type: ConfigNestedValueType::Uint8,
1740 max_count: std::u32::MAX,
1741 },
1742 ConfigVectorValue::Uint16Vector(_) => ConfigValueType::Vector {
1743 nested_type: ConfigNestedValueType::Uint16,
1744 max_count: std::u32::MAX,
1745 },
1746 ConfigVectorValue::Uint32Vector(_) => ConfigValueType::Vector {
1747 nested_type: ConfigNestedValueType::Uint32,
1748 max_count: std::u32::MAX,
1749 },
1750 ConfigVectorValue::Uint64Vector(_) => ConfigValueType::Vector {
1751 nested_type: ConfigNestedValueType::Uint64,
1752 max_count: std::u32::MAX,
1753 },
1754 ConfigVectorValue::Int8Vector(_) => ConfigValueType::Vector {
1755 nested_type: ConfigNestedValueType::Int8,
1756 max_count: std::u32::MAX,
1757 },
1758 ConfigVectorValue::Int16Vector(_) => ConfigValueType::Vector {
1759 nested_type: ConfigNestedValueType::Int16,
1760 max_count: std::u32::MAX,
1761 },
1762 ConfigVectorValue::Int32Vector(_) => ConfigValueType::Vector {
1763 nested_type: ConfigNestedValueType::Int32,
1764 max_count: std::u32::MAX,
1765 },
1766 ConfigVectorValue::Int64Vector(_) => ConfigValueType::Vector {
1767 nested_type: ConfigNestedValueType::Int64,
1768 max_count: std::u32::MAX,
1769 },
1770 ConfigVectorValue::StringVector(_) => ConfigValueType::Vector {
1771 nested_type: ConfigNestedValueType::String { max_size: std::u32::MAX },
1772 max_count: std::u32::MAX,
1773 },
1774 }
1775 }
1776}
1777
1778impl fmt::Display for ConfigVectorValue {
1779 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1780 use ConfigVectorValue::*;
1781 macro_rules! print_list {
1782 ($f:ident, $list:ident) => {{
1783 $f.write_str("[")?;
1784
1785 for (i, item) in $list.iter().enumerate() {
1786 if i > 0 {
1787 $f.write_str(", ")?;
1788 }
1789 write!($f, "{}", item)?;
1790 }
1791
1792 $f.write_str("]")
1793 }};
1794 }
1795 match self {
1796 BoolVector(l) => print_list!(f, l),
1797 Uint8Vector(l) => print_list!(f, l),
1798 Uint16Vector(l) => print_list!(f, l),
1799 Uint32Vector(l) => print_list!(f, l),
1800 Uint64Vector(l) => print_list!(f, l),
1801 Int8Vector(l) => print_list!(f, l),
1802 Int16Vector(l) => print_list!(f, l),
1803 Int32Vector(l) => print_list!(f, l),
1804 Int64Vector(l) => print_list!(f, l),
1805 StringVector(l) => {
1806 f.write_str("[")?;
1807 for (i, item) in l.iter().enumerate() {
1808 if i > 0 {
1809 f.write_str(", ")?;
1810 }
1811 write!(f, "\"{}\"", item)?;
1812 }
1813 f.write_str("]")
1814 }
1815 }
1816 }
1817}
1818
1819#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
1820#[derive(FidlDecl, Debug, Clone, PartialEq, Eq)]
1821#[fidl_decl(fidl_table = "fdecl::RunnerRegistration")]
1822pub struct RunnerRegistration {
1823 pub source_name: Name,
1824 pub target_name: Name,
1825 pub source: RegistrationSource,
1826}
1827
1828impl SourceName for RunnerRegistration {
1829 fn source_name(&self) -> &Name {
1830 &self.source_name
1831 }
1832}
1833
1834impl RegistrationDeclCommon for RunnerRegistration {
1835 const TYPE: &'static str = "runner";
1836
1837 fn source(&self) -> &RegistrationSource {
1838 &self.source
1839 }
1840}
1841
1842#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
1843#[derive(FidlDecl, Debug, Clone, PartialEq, Eq)]
1844#[fidl_decl(fidl_table = "fdecl::ResolverRegistration")]
1845pub struct ResolverRegistration {
1846 pub resolver: Name,
1847 pub source: RegistrationSource,
1848 pub scheme: String,
1849}
1850
1851impl SourceName for ResolverRegistration {
1852 fn source_name(&self) -> &Name {
1853 &self.resolver
1854 }
1855}
1856
1857impl RegistrationDeclCommon for ResolverRegistration {
1858 const TYPE: &'static str = "resolver";
1859
1860 fn source(&self) -> &RegistrationSource {
1861 &self.source
1862 }
1863}
1864
1865#[derive(FidlDecl, Debug, Clone, PartialEq, Eq)]
1866#[fidl_decl(fidl_union = "fdecl::DebugRegistration")]
1867pub enum DebugRegistration {
1868 Protocol(DebugProtocolRegistration),
1869}
1870
1871impl RegistrationDeclCommon for DebugRegistration {
1872 const TYPE: &'static str = "debug_protocol";
1873
1874 fn source(&self) -> &RegistrationSource {
1875 match self {
1876 DebugRegistration::Protocol(protocol_reg) => &protocol_reg.source,
1877 }
1878 }
1879}
1880
1881impl SourceName for DebugRegistration {
1882 fn source_name(&self) -> &Name {
1883 match self {
1884 DebugRegistration::Protocol(protocol_reg) => &protocol_reg.source_name,
1885 }
1886 }
1887}
1888
1889#[derive(FidlDecl, Debug, Clone, PartialEq, Eq)]
1890#[fidl_decl(fidl_table = "fdecl::DebugProtocolRegistration")]
1891pub struct DebugProtocolRegistration {
1892 pub source_name: Name,
1893 pub source: RegistrationSource,
1894 pub target_name: Name,
1895}
1896
1897#[derive(FidlDecl, Debug, Clone, PartialEq)]
1898#[fidl_decl(fidl_table = "fdecl::Program")]
1899pub struct ProgramDecl {
1900 pub runner: Option<Name>,
1901 pub info: fdata::Dictionary,
1902}
1903
1904impl Default for ProgramDecl {
1905 fn default() -> Self {
1906 Self { runner: None, info: fdata::Dictionary::default() }
1907 }
1908}
1909
1910fidl_translations_identical!([u8; 32]);
1911fidl_translations_identical!(u8);
1912fidl_translations_identical!(u16);
1913fidl_translations_identical!(u32);
1914fidl_translations_identical!(u64);
1915fidl_translations_identical!(i8);
1916fidl_translations_identical!(i16);
1917fidl_translations_identical!(i32);
1918fidl_translations_identical!(i64);
1919fidl_translations_identical!(bool);
1920fidl_translations_identical!(String);
1921fidl_translations_identical!(Vec<Name>);
1922fidl_translations_identical!(fdecl::StartupMode);
1923fidl_translations_identical!(fdecl::OnTerminate);
1924fidl_translations_identical!(fdecl::Durability);
1925fidl_translations_identical!(fdata::Dictionary);
1926fidl_translations_identical!(fio::Operations);
1927fidl_translations_identical!(fdecl::EnvironmentExtends);
1928fidl_translations_identical!(fdecl::StorageId);
1929fidl_translations_identical!(Vec<fprocess::HandleInfo>);
1930fidl_translations_identical!(fsys::ServiceInstance);
1931fidl_translations_from_into!(cm_types::AllowedOffers, fdecl::AllowedOffers);
1932
1933#[cfg_attr(feature = "serde", derive(Deserialize, Serialize), serde(rename_all = "snake_case"))]
1934#[derive(Debug, Clone, PartialEq, Eq)]
1935pub enum DependencyType {
1936 Strong,
1937 Weak,
1938}
1939
1940impl Default for DependencyType {
1941 fn default() -> Self {
1942 Self::Strong
1943 }
1944}
1945
1946fidl_translations_symmetrical_enums!(fdecl::DependencyType, DependencyType, Strong, Weak);
1947
1948impl UseDecl {
1949 pub fn path(&self) -> Option<&Path> {
1950 match self {
1951 UseDecl::Service(d) => Some(&d.target_path),
1952 UseDecl::Protocol(d) => Some(&d.target_path),
1953 UseDecl::Directory(d) => Some(&d.target_path),
1954 UseDecl::Storage(d) => Some(&d.target_path),
1955 UseDecl::EventStream(d) => Some(&d.target_path),
1956 #[cfg(fuchsia_api_level_at_least = "HEAD")]
1957 UseDecl::Runner(_) => None,
1958 #[cfg(fuchsia_api_level_at_least = "20")]
1959 UseDecl::Config(_) => None,
1960 }
1961 }
1962
1963 pub fn name(&self) -> Option<&Name> {
1964 match self {
1965 UseDecl::Storage(storage_decl) => Some(&storage_decl.source_name),
1966 UseDecl::EventStream(_) => None,
1967 UseDecl::Service(_) | UseDecl::Protocol(_) | UseDecl::Directory(_) => None,
1968 #[cfg(fuchsia_api_level_at_least = "HEAD")]
1969 UseDecl::Runner(_) => None,
1970 #[cfg(fuchsia_api_level_at_least = "20")]
1971 UseDecl::Config(_) => None,
1972 }
1973 }
1974}
1975
1976impl SourceName for UseDecl {
1977 fn source_name(&self) -> &Name {
1978 match self {
1979 UseDecl::Storage(storage_decl) => &storage_decl.source_name,
1980 UseDecl::Service(service_decl) => &service_decl.source_name,
1981 UseDecl::Protocol(protocol_decl) => &protocol_decl.source_name,
1982 UseDecl::Directory(directory_decl) => &directory_decl.source_name,
1983 UseDecl::EventStream(event_stream_decl) => &event_stream_decl.source_name,
1984 #[cfg(fuchsia_api_level_at_least = "HEAD")]
1985 UseDecl::Runner(runner_decl) => &runner_decl.source_name,
1986 #[cfg(fuchsia_api_level_at_least = "20")]
1987 UseDecl::Config(u) => &u.source_name,
1988 }
1989 }
1990}
1991
1992impl SourcePath for UseDecl {
1993 fn source_path(&self) -> BorrowedSeparatedPath<'_> {
1994 match self {
1995 UseDecl::Service(u) => u.source_path(),
1996 UseDecl::Protocol(u) => u.source_path(),
1997 UseDecl::Directory(u) => u.source_path(),
1998 UseDecl::Storage(u) => u.source_path(),
1999 UseDecl::EventStream(u) => u.source_path(),
2000 #[cfg(fuchsia_api_level_at_least = "HEAD")]
2001 UseDecl::Runner(u) => u.source_path(),
2002 #[cfg(fuchsia_api_level_at_least = "20")]
2003 UseDecl::Config(u) => u.source_path(),
2004 }
2005 }
2006}
2007
2008pub trait SourceName {
2010 fn source_name(&self) -> &Name;
2011}
2012
2013pub trait UseDeclCommon: SourceName + SourcePath + Send + Sync {
2015 fn source(&self) -> &UseSource;
2016 fn availability(&self) -> &Availability;
2017}
2018
2019pub trait RegistrationDeclCommon: SourceName + Send + Sync {
2021 const TYPE: &'static str;
2023 fn source(&self) -> &RegistrationSource;
2024}
2025
2026pub trait OfferDeclCommon: SourceName + SourcePath + fmt::Debug + Send + Sync {
2028 fn target_name(&self) -> &Name;
2029 fn target(&self) -> &OfferTarget;
2030 fn source(&self) -> &OfferSource;
2031 fn availability(&self) -> &Availability;
2032}
2033
2034pub trait ExposeDeclCommon: SourceName + SourcePath + fmt::Debug + Send + Sync {
2036 fn target_name(&self) -> &Name;
2037 fn target(&self) -> &ExposeTarget;
2038 fn source(&self) -> &ExposeSource;
2039 fn availability(&self) -> &Availability;
2040}
2041
2042#[cfg_attr(feature = "serde", derive(Deserialize, Serialize), serde(rename_all = "snake_case"))]
2046#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, EnumIter)]
2047pub enum CapabilityTypeName {
2048 Directory,
2049 EventStream,
2050 Protocol,
2051 Resolver,
2052 Runner,
2053 Service,
2054 Storage,
2055 Dictionary,
2056 Config,
2057}
2058
2059impl std::str::FromStr for CapabilityTypeName {
2060 type Err = Error;
2061
2062 fn from_str(s: &str) -> Result<Self, Self::Err> {
2063 match s {
2064 "directory" => Ok(CapabilityTypeName::Directory),
2065 "event_stream" => Ok(CapabilityTypeName::EventStream),
2066 "protocol" => Ok(CapabilityTypeName::Protocol),
2067 "resolver" => Ok(CapabilityTypeName::Resolver),
2068 "runner" => Ok(CapabilityTypeName::Runner),
2069 "service" => Ok(CapabilityTypeName::Service),
2070 "storage" => Ok(CapabilityTypeName::Storage),
2071 "dictionary" => Ok(CapabilityTypeName::Dictionary),
2072 "configuration" => Ok(CapabilityTypeName::Config),
2073 _ => Err(Error::ParseCapabilityTypeName { raw: s.to_string() }),
2074 }
2075 }
2076}
2077
2078impl FidlIntoNative<CapabilityTypeName> for String {
2079 fn fidl_into_native(self) -> CapabilityTypeName {
2080 self.parse().unwrap()
2081 }
2082}
2083
2084impl NativeIntoFidl<String> for CapabilityTypeName {
2085 fn native_into_fidl(self) -> String {
2086 self.to_string()
2087 }
2088}
2089
2090impl fmt::Display for CapabilityTypeName {
2091 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2092 let display_name = match &self {
2093 CapabilityTypeName::Directory => "directory",
2094 CapabilityTypeName::EventStream => "event_stream",
2095 CapabilityTypeName::Protocol => "protocol",
2096 CapabilityTypeName::Resolver => "resolver",
2097 CapabilityTypeName::Runner => "runner",
2098 CapabilityTypeName::Service => "service",
2099 CapabilityTypeName::Storage => "storage",
2100 CapabilityTypeName::Dictionary => "dictionary",
2101 CapabilityTypeName::Config => "configuration",
2102 };
2103 write!(f, "{}", display_name)
2104 }
2105}
2106
2107impl From<&UseDecl> for CapabilityTypeName {
2108 fn from(use_decl: &UseDecl) -> Self {
2109 match use_decl {
2110 UseDecl::Service(_) => Self::Service,
2111 UseDecl::Protocol(_) => Self::Protocol,
2112 UseDecl::Directory(_) => Self::Directory,
2113 UseDecl::Storage(_) => Self::Storage,
2114 UseDecl::EventStream(_) => Self::EventStream,
2115 #[cfg(fuchsia_api_level_at_least = "HEAD")]
2116 UseDecl::Runner(_) => Self::Runner,
2117 #[cfg(fuchsia_api_level_at_least = "20")]
2118 UseDecl::Config(_) => Self::Config,
2119 }
2120 }
2121}
2122
2123impl From<&OfferDecl> for CapabilityTypeName {
2124 fn from(offer_decl: &OfferDecl) -> Self {
2125 match offer_decl {
2126 OfferDecl::Service(_) => Self::Service,
2127 OfferDecl::Protocol(_) => Self::Protocol,
2128 OfferDecl::Directory(_) => Self::Directory,
2129 OfferDecl::Storage(_) => Self::Storage,
2130 OfferDecl::Runner(_) => Self::Runner,
2131 OfferDecl::Resolver(_) => Self::Resolver,
2132 OfferDecl::EventStream(_) => Self::EventStream,
2133 #[cfg(fuchsia_api_level_at_least = "25")]
2134 OfferDecl::Dictionary(_) => Self::Dictionary,
2135 #[cfg(fuchsia_api_level_at_least = "20")]
2136 OfferDecl::Config(_) => Self::Config,
2137 }
2138 }
2139}
2140
2141impl From<&ExposeDecl> for CapabilityTypeName {
2142 fn from(expose_decl: &ExposeDecl) -> Self {
2143 match expose_decl {
2144 ExposeDecl::Service(_) => Self::Service,
2145 ExposeDecl::Protocol(_) => Self::Protocol,
2146 ExposeDecl::Directory(_) => Self::Directory,
2147 ExposeDecl::Runner(_) => Self::Runner,
2148 ExposeDecl::Resolver(_) => Self::Resolver,
2149 #[cfg(fuchsia_api_level_at_least = "25")]
2150 ExposeDecl::Dictionary(_) => Self::Dictionary,
2151 #[cfg(fuchsia_api_level_at_least = "20")]
2152 ExposeDecl::Config(_) => Self::Config,
2153 }
2154 }
2155}
2156
2157impl From<&CapabilityDecl> for CapabilityTypeName {
2158 fn from(capability: &CapabilityDecl) -> Self {
2159 match capability {
2160 CapabilityDecl::Service(_) => Self::Service,
2161 CapabilityDecl::Protocol(_) => Self::Protocol,
2162 CapabilityDecl::Directory(_) => Self::Directory,
2163 CapabilityDecl::Storage(_) => Self::Storage,
2164 CapabilityDecl::Runner(_) => Self::Runner,
2165 CapabilityDecl::Resolver(_) => Self::Resolver,
2166 CapabilityDecl::EventStream(_) => Self::EventStream,
2167 #[cfg(fuchsia_api_level_at_least = "25")]
2168 CapabilityDecl::Dictionary(_) => Self::Dictionary,
2169 #[cfg(fuchsia_api_level_at_least = "20")]
2170 CapabilityDecl::Config(_) => Self::Config,
2171 }
2172 }
2173}
2174
2175impl From<CapabilityTypeName> for fio::DirentType {
2176 fn from(value: CapabilityTypeName) -> Self {
2177 match value {
2178 CapabilityTypeName::Directory => fio::DirentType::Directory,
2179 CapabilityTypeName::EventStream => fio::DirentType::Service,
2180 CapabilityTypeName::Protocol => fio::DirentType::Service,
2181 CapabilityTypeName::Service => fio::DirentType::Directory,
2182 CapabilityTypeName::Storage => fio::DirentType::Directory,
2183 CapabilityTypeName::Dictionary => fio::DirentType::Directory,
2184 CapabilityTypeName::Resolver => fio::DirentType::Service,
2185 CapabilityTypeName::Runner => fio::DirentType::Service,
2186 CapabilityTypeName::Config => fio::DirentType::Unknown,
2188 }
2189 }
2190}
2191
2192impl FidlIntoNative<HashMap<String, DictionaryValue>> for fdata::Dictionary {
2194 fn fidl_into_native(self) -> HashMap<String, DictionaryValue> {
2195 from_fidl_dict(self)
2196 }
2197}
2198
2199impl NativeIntoFidl<fdata::Dictionary> for HashMap<String, DictionaryValue> {
2200 fn native_into_fidl(self) -> fdata::Dictionary {
2201 to_fidl_dict(self)
2202 }
2203}
2204
2205impl FidlIntoNative<BTreeMap<String, DictionaryValue>> for fdata::Dictionary {
2206 fn fidl_into_native(self) -> BTreeMap<String, DictionaryValue> {
2207 from_fidl_dict_btree(self)
2208 }
2209}
2210
2211impl NativeIntoFidl<fdata::Dictionary> for BTreeMap<String, DictionaryValue> {
2212 fn native_into_fidl(self) -> fdata::Dictionary {
2213 to_fidl_dict_btree(self)
2214 }
2215}
2216
2217#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2218pub enum DictionaryValue {
2219 Str(String),
2220 StrVec(Vec<String>),
2221 Null,
2222}
2223
2224impl FidlIntoNative<DictionaryValue> for Option<Box<fdata::DictionaryValue>> {
2225 fn fidl_into_native(self) -> DictionaryValue {
2226 #[allow(unreachable_patterns)]
2230 match self {
2231 Some(v) => match *v {
2232 fdata::DictionaryValue::Str(s) => DictionaryValue::Str(s),
2233 fdata::DictionaryValue::StrVec(ss) => DictionaryValue::StrVec(ss),
2234 _ => DictionaryValue::Null,
2235 },
2236 None => DictionaryValue::Null,
2237 }
2238 }
2239}
2240
2241impl NativeIntoFidl<Option<Box<fdata::DictionaryValue>>> for DictionaryValue {
2242 fn native_into_fidl(self) -> Option<Box<fdata::DictionaryValue>> {
2243 match self {
2244 DictionaryValue::Str(s) => Some(Box::new(fdata::DictionaryValue::Str(s))),
2245 DictionaryValue::StrVec(ss) => Some(Box::new(fdata::DictionaryValue::StrVec(ss))),
2246 DictionaryValue::Null => None,
2247 }
2248 }
2249}
2250
2251fn from_fidl_dict(dict: fdata::Dictionary) -> HashMap<String, DictionaryValue> {
2252 match dict.entries {
2253 Some(entries) => entries.into_iter().map(|e| (e.key, e.value.fidl_into_native())).collect(),
2254 _ => HashMap::new(),
2255 }
2256}
2257
2258fn to_fidl_dict(dict: HashMap<String, DictionaryValue>) -> fdata::Dictionary {
2259 fdata::Dictionary {
2260 entries: Some(
2261 dict.into_iter()
2262 .map(|(key, value)| fdata::DictionaryEntry { key, value: value.native_into_fidl() })
2263 .collect(),
2264 ),
2265 ..Default::default()
2266 }
2267}
2268
2269fn from_fidl_dict_btree(dict: fdata::Dictionary) -> BTreeMap<String, DictionaryValue> {
2270 match dict.entries {
2271 Some(entries) => entries.into_iter().map(|e| (e.key, e.value.fidl_into_native())).collect(),
2272 _ => BTreeMap::new(),
2273 }
2274}
2275
2276fn to_fidl_dict_btree(dict: BTreeMap<String, DictionaryValue>) -> fdata::Dictionary {
2277 fdata::Dictionary {
2278 entries: Some(
2279 dict.into_iter()
2280 .map(|(key, value)| fdata::DictionaryEntry { key, value: value.native_into_fidl() })
2281 .collect(),
2282 ),
2283 ..Default::default()
2284 }
2285}
2286
2287#[cfg_attr(feature = "serde", derive(Deserialize, Serialize), serde(rename_all = "snake_case"))]
2288#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2289pub enum UseSource {
2290 Parent,
2291 Framework,
2292 Debug,
2293 Self_,
2294 Capability(Name),
2295 Child(Name),
2296 Collection(Name),
2297 #[cfg(fuchsia_api_level_at_least = "HEAD")]
2298 Environment,
2299}
2300
2301impl std::fmt::Display for UseSource {
2302 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2303 match self {
2304 Self::Framework => write!(f, "framework"),
2305 Self::Parent => write!(f, "parent"),
2306 Self::Debug => write!(f, "debug environment"),
2307 Self::Self_ => write!(f, "self"),
2308 Self::Capability(c) => write!(f, "capability `{}`", c),
2309 Self::Child(c) => write!(f, "child `#{}`", c),
2310 Self::Collection(c) => write!(f, "collection `#{}`", c),
2311 #[cfg(fuchsia_api_level_at_least = "HEAD")]
2312 Self::Environment => write!(f, "environment"),
2313 }
2314 }
2315}
2316
2317impl FidlIntoNative<UseSource> for fdecl::Ref {
2318 fn fidl_into_native(self) -> UseSource {
2319 match self {
2320 fdecl::Ref::Parent(_) => UseSource::Parent,
2321 fdecl::Ref::Framework(_) => UseSource::Framework,
2322 fdecl::Ref::Debug(_) => UseSource::Debug,
2323 fdecl::Ref::Self_(_) => UseSource::Self_,
2324 fdecl::Ref::Capability(c) => UseSource::Capability(c.name.parse().unwrap()),
2326 fdecl::Ref::Child(c) => UseSource::Child(c.name.parse().unwrap()),
2327 fdecl::Ref::Collection(c) => UseSource::Collection(c.name.parse().unwrap()),
2328 #[cfg(fuchsia_api_level_at_least = "HEAD")]
2329 fdecl::Ref::Environment(_) => UseSource::Environment,
2330 _ => panic!("invalid UseSource variant"),
2331 }
2332 }
2333}
2334
2335impl NativeIntoFidl<fdecl::Ref> for UseSource {
2336 fn native_into_fidl(self) -> fdecl::Ref {
2337 match self {
2338 UseSource::Parent => fdecl::Ref::Parent(fdecl::ParentRef {}),
2339 UseSource::Framework => fdecl::Ref::Framework(fdecl::FrameworkRef {}),
2340 UseSource::Debug => fdecl::Ref::Debug(fdecl::DebugRef {}),
2341 UseSource::Self_ => fdecl::Ref::Self_(fdecl::SelfRef {}),
2342 UseSource::Capability(name) => {
2343 fdecl::Ref::Capability(fdecl::CapabilityRef { name: name.to_string() })
2344 }
2345 UseSource::Child(name) => {
2346 fdecl::Ref::Child(fdecl::ChildRef { name: name.to_string(), collection: None })
2347 }
2348 UseSource::Collection(name) => {
2349 fdecl::Ref::Collection(fdecl::CollectionRef { name: name.to_string() })
2350 }
2351 #[cfg(fuchsia_api_level_at_least = "HEAD")]
2352 UseSource::Environment => fdecl::Ref::Environment(fdecl::EnvironmentRef {}),
2353 }
2354 }
2355}
2356
2357#[cfg_attr(feature = "serde", derive(Deserialize, Serialize), serde(rename_all = "snake_case"))]
2358#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2359pub enum EventScope {
2360 Child(ChildRef),
2361 Collection(Name),
2362}
2363
2364impl FidlIntoNative<EventScope> for fdecl::Ref {
2365 fn fidl_into_native(self) -> EventScope {
2366 match self {
2367 fdecl::Ref::Child(c) => {
2368 if let Some(_) = c.collection {
2369 panic!("Dynamic children scopes are not supported for EventStreams");
2370 } else {
2371 EventScope::Child(ChildRef { name: c.name.parse().unwrap(), collection: None })
2372 }
2373 }
2374 fdecl::Ref::Collection(collection) => {
2375 EventScope::Collection(collection.name.parse().unwrap())
2377 }
2378 _ => panic!("invalid EventScope variant"),
2379 }
2380 }
2381}
2382
2383impl NativeIntoFidl<fdecl::Ref> for EventScope {
2384 fn native_into_fidl(self) -> fdecl::Ref {
2385 match self {
2386 EventScope::Child(child) => fdecl::Ref::Child(child.native_into_fidl()),
2387 EventScope::Collection(name) => {
2388 fdecl::Ref::Collection(fdecl::CollectionRef { name: name.native_into_fidl() })
2389 }
2390 }
2391 }
2392}
2393
2394#[cfg_attr(feature = "serde", derive(Deserialize, Serialize), serde(rename_all = "snake_case"))]
2395#[derive(Debug, Clone, PartialEq, Eq)]
2396pub enum OfferSource {
2397 Framework,
2398 Parent,
2399 Child(ChildRef),
2400 Collection(Name),
2401 Self_,
2402 Capability(Name),
2403 Void,
2404}
2405
2406impl std::fmt::Display for OfferSource {
2407 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2408 match self {
2409 Self::Framework => write!(f, "framework"),
2410 Self::Parent => write!(f, "parent"),
2411 Self::Child(c) => write!(f, "child `#{}`", c),
2412 Self::Collection(c) => write!(f, "collection `#{}`", c),
2413 Self::Self_ => write!(f, "self"),
2414 Self::Capability(c) => write!(f, "capability `{}`", c),
2415 Self::Void => write!(f, "void"),
2416 }
2417 }
2418}
2419
2420impl FidlIntoNative<OfferSource> for fdecl::Ref {
2421 fn fidl_into_native(self) -> OfferSource {
2422 match self {
2423 fdecl::Ref::Parent(_) => OfferSource::Parent,
2424 fdecl::Ref::Self_(_) => OfferSource::Self_,
2425 fdecl::Ref::Child(c) => OfferSource::Child(c.fidl_into_native()),
2426 fdecl::Ref::Collection(c) => OfferSource::Collection(c.name.parse().unwrap()),
2428 fdecl::Ref::Framework(_) => OfferSource::Framework,
2429 fdecl::Ref::Capability(c) => OfferSource::Capability(c.name.parse().unwrap()),
2431 fdecl::Ref::VoidType(_) => OfferSource::Void,
2432 _ => panic!("invalid OfferSource variant"),
2433 }
2434 }
2435}
2436
2437impl NativeIntoFidl<fdecl::Ref> for OfferSource {
2438 fn native_into_fidl(self) -> fdecl::Ref {
2439 match self {
2440 OfferSource::Parent => fdecl::Ref::Parent(fdecl::ParentRef {}),
2441 OfferSource::Self_ => fdecl::Ref::Self_(fdecl::SelfRef {}),
2442 OfferSource::Child(c) => fdecl::Ref::Child(c.native_into_fidl()),
2443 OfferSource::Collection(name) => {
2444 fdecl::Ref::Collection(fdecl::CollectionRef { name: name.native_into_fidl() })
2445 }
2446 OfferSource::Framework => fdecl::Ref::Framework(fdecl::FrameworkRef {}),
2447 OfferSource::Capability(name) => {
2448 fdecl::Ref::Capability(fdecl::CapabilityRef { name: name.to_string() })
2449 }
2450 OfferSource::Void => fdecl::Ref::VoidType(fdecl::VoidRef {}),
2451 }
2452 }
2453}
2454
2455#[cfg_attr(feature = "serde", derive(Deserialize, Serialize), serde(rename_all = "snake_case"))]
2456#[derive(Debug, Clone, PartialEq, Eq)]
2457pub enum ExposeSource {
2458 Self_,
2459 Child(Name),
2460 Collection(Name),
2461 Framework,
2462 Capability(Name),
2463 Void,
2464}
2465
2466impl std::fmt::Display for ExposeSource {
2467 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2468 match self {
2469 Self::Framework => write!(f, "framework"),
2470 Self::Child(c) => write!(f, "child `#{}`", c),
2471 Self::Collection(c) => write!(f, "collection `#{}`", c),
2472 Self::Self_ => write!(f, "self"),
2473 Self::Capability(c) => write!(f, "capability `{}`", c),
2474 Self::Void => write!(f, "void"),
2475 }
2476 }
2477}
2478
2479impl FidlIntoNative<ExposeSource> for fdecl::Ref {
2480 fn fidl_into_native(self) -> ExposeSource {
2481 match self {
2482 fdecl::Ref::Self_(_) => ExposeSource::Self_,
2483 fdecl::Ref::Child(c) => ExposeSource::Child(c.name.parse().unwrap()),
2485 fdecl::Ref::Collection(c) => ExposeSource::Collection(c.name.parse().unwrap()),
2487 fdecl::Ref::Framework(_) => ExposeSource::Framework,
2488 fdecl::Ref::Capability(c) => ExposeSource::Capability(c.name.parse().unwrap()),
2490 fdecl::Ref::VoidType(_) => ExposeSource::Void,
2491 _ => panic!("invalid ExposeSource variant"),
2492 }
2493 }
2494}
2495
2496impl NativeIntoFidl<fdecl::Ref> for ExposeSource {
2497 fn native_into_fidl(self) -> fdecl::Ref {
2498 match self {
2499 ExposeSource::Self_ => fdecl::Ref::Self_(fdecl::SelfRef {}),
2500 ExposeSource::Child(name) => fdecl::Ref::Child(fdecl::ChildRef {
2501 name: name.native_into_fidl(),
2502 collection: None,
2503 }),
2504 ExposeSource::Collection(name) => {
2505 fdecl::Ref::Collection(fdecl::CollectionRef { name: name.native_into_fidl() })
2506 }
2507 ExposeSource::Framework => fdecl::Ref::Framework(fdecl::FrameworkRef {}),
2508 ExposeSource::Capability(name) => {
2509 fdecl::Ref::Capability(fdecl::CapabilityRef { name: name.to_string() })
2510 }
2511 ExposeSource::Void => fdecl::Ref::VoidType(fdecl::VoidRef {}),
2512 }
2513 }
2514}
2515
2516#[cfg_attr(feature = "serde", derive(Deserialize, Serialize), serde(rename_all = "snake_case"))]
2517#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
2518pub enum ExposeTarget {
2519 Parent,
2520 Framework,
2521}
2522
2523impl std::fmt::Display for ExposeTarget {
2524 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2525 match self {
2526 Self::Framework => write!(f, "framework"),
2527 Self::Parent => write!(f, "parent"),
2528 }
2529 }
2530}
2531
2532impl FidlIntoNative<ExposeTarget> for fdecl::Ref {
2533 fn fidl_into_native(self) -> ExposeTarget {
2534 match self {
2535 fdecl::Ref::Parent(_) => ExposeTarget::Parent,
2536 fdecl::Ref::Framework(_) => ExposeTarget::Framework,
2537 _ => panic!("invalid ExposeTarget variant"),
2538 }
2539 }
2540}
2541
2542impl NativeIntoFidl<fdecl::Ref> for ExposeTarget {
2543 fn native_into_fidl(self) -> fdecl::Ref {
2544 match self {
2545 ExposeTarget::Parent => fdecl::Ref::Parent(fdecl::ParentRef {}),
2546 ExposeTarget::Framework => fdecl::Ref::Framework(fdecl::FrameworkRef {}),
2547 }
2548 }
2549}
2550
2551#[derive(Debug, Clone, PartialEq, Eq)]
2553pub struct ServiceSource<T> {
2554 pub source: T,
2556 pub source_name: Name,
2558}
2559
2560#[cfg_attr(feature = "serde", derive(Deserialize, Serialize), serde(rename_all = "snake_case"))]
2561#[derive(Debug, Clone, PartialEq, Eq)]
2562pub enum StorageDirectorySource {
2563 Parent,
2564 Self_,
2565 Child(String),
2566}
2567
2568impl FidlIntoNative<StorageDirectorySource> for fdecl::Ref {
2569 fn fidl_into_native(self) -> StorageDirectorySource {
2570 match self {
2571 fdecl::Ref::Parent(_) => StorageDirectorySource::Parent,
2572 fdecl::Ref::Self_(_) => StorageDirectorySource::Self_,
2573 fdecl::Ref::Child(c) => StorageDirectorySource::Child(c.name),
2574 _ => panic!("invalid OfferDirectorySource variant"),
2575 }
2576 }
2577}
2578
2579impl NativeIntoFidl<fdecl::Ref> for StorageDirectorySource {
2580 fn native_into_fidl(self) -> fdecl::Ref {
2581 match self {
2582 StorageDirectorySource::Parent => fdecl::Ref::Parent(fdecl::ParentRef {}),
2583 StorageDirectorySource::Self_ => fdecl::Ref::Self_(fdecl::SelfRef {}),
2584 StorageDirectorySource::Child(child_name) => {
2585 fdecl::Ref::Child(fdecl::ChildRef { name: child_name, collection: None })
2586 }
2587 }
2588 }
2589}
2590
2591#[cfg_attr(feature = "serde", derive(Deserialize, Serialize), serde(rename_all = "snake_case"))]
2592#[derive(Debug, Clone, PartialEq, Eq)]
2593pub enum DictionarySource {
2594 Parent,
2595 Self_,
2596 Child(ChildRef),
2597}
2598
2599impl FidlIntoNative<DictionarySource> for fdecl::Ref {
2600 fn fidl_into_native(self) -> DictionarySource {
2601 match self {
2602 Self::Parent(_) => DictionarySource::Parent,
2603 Self::Self_(_) => DictionarySource::Self_,
2604 Self::Child(c) => DictionarySource::Child(c.fidl_into_native()),
2605 _ => panic!("invalid DictionarySource variant"),
2606 }
2607 }
2608}
2609
2610impl NativeIntoFidl<fdecl::Ref> for DictionarySource {
2611 fn native_into_fidl(self) -> fdecl::Ref {
2612 match self {
2613 Self::Parent => fdecl::Ref::Parent(fdecl::ParentRef {}),
2614 Self::Self_ => fdecl::Ref::Self_(fdecl::SelfRef {}),
2615 Self::Child(c) => fdecl::Ref::Child(c.native_into_fidl()),
2616 }
2617 }
2618}
2619
2620#[cfg_attr(feature = "serde", derive(Deserialize, Serialize), serde(rename_all = "snake_case"))]
2621#[derive(Debug, Clone, PartialEq, Eq)]
2622pub enum RegistrationSource {
2623 Parent,
2624 Self_,
2625 Child(String),
2626}
2627
2628impl FidlIntoNative<RegistrationSource> for fdecl::Ref {
2629 fn fidl_into_native(self) -> RegistrationSource {
2630 match self {
2631 fdecl::Ref::Parent(_) => RegistrationSource::Parent,
2632 fdecl::Ref::Self_(_) => RegistrationSource::Self_,
2633 fdecl::Ref::Child(c) => RegistrationSource::Child(c.name),
2634 _ => panic!("invalid RegistrationSource variant"),
2635 }
2636 }
2637}
2638
2639impl NativeIntoFidl<fdecl::Ref> for RegistrationSource {
2640 fn native_into_fidl(self) -> fdecl::Ref {
2641 match self {
2642 RegistrationSource::Parent => fdecl::Ref::Parent(fdecl::ParentRef {}),
2643 RegistrationSource::Self_ => fdecl::Ref::Self_(fdecl::SelfRef {}),
2644 RegistrationSource::Child(child_name) => {
2645 fdecl::Ref::Child(fdecl::ChildRef { name: child_name, collection: None })
2646 }
2647 }
2648 }
2649}
2650
2651#[cfg_attr(feature = "serde", derive(Deserialize, Serialize), serde(rename_all = "snake_case"))]
2652#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2653pub enum OfferTarget {
2654 Child(ChildRef),
2655 Collection(Name),
2656 Capability(Name),
2657}
2658
2659impl std::fmt::Display for OfferTarget {
2660 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2661 match self {
2662 Self::Child(c) => write!(f, "child `#{}`", c),
2663 Self::Collection(c) => write!(f, "collection `#{}`", c),
2664 Self::Capability(c) => write!(f, "capability `#{}`", c),
2665 }
2666 }
2667}
2668
2669impl FidlIntoNative<OfferTarget> for fdecl::Ref {
2670 fn fidl_into_native(self) -> OfferTarget {
2671 match self {
2672 fdecl::Ref::Child(c) => OfferTarget::Child(c.fidl_into_native()),
2673 fdecl::Ref::Collection(c) => OfferTarget::Collection(c.name.parse().unwrap()),
2675 fdecl::Ref::Capability(c) => OfferTarget::Capability(c.name.parse().unwrap()),
2676 _ => panic!("invalid OfferTarget variant"),
2677 }
2678 }
2679}
2680
2681impl NativeIntoFidl<fdecl::Ref> for OfferTarget {
2682 fn native_into_fidl(self) -> fdecl::Ref {
2683 match self {
2684 OfferTarget::Child(c) => fdecl::Ref::Child(c.native_into_fidl()),
2685 OfferTarget::Collection(collection_name) => {
2686 fdecl::Ref::Collection(fdecl::CollectionRef {
2687 name: collection_name.native_into_fidl(),
2688 })
2689 }
2690 OfferTarget::Capability(capability_name) => {
2691 fdecl::Ref::Capability(fdecl::CapabilityRef {
2692 name: capability_name.native_into_fidl(),
2693 })
2694 }
2695 }
2696 }
2697}
2698
2699impl TryFrom<fdecl::Component> for ComponentDecl {
2703 type Error = Error;
2704
2705 fn try_from(decl: fdecl::Component) -> Result<Self, Self::Error> {
2706 cm_fidl_validator::validate(&decl).map_err(|err| Error::Validate { err })?;
2707 Ok(decl.fidl_into_native())
2708 }
2709}
2710
2711impl From<ComponentDecl> for fdecl::Component {
2713 fn from(decl: ComponentDecl) -> Self {
2714 decl.native_into_fidl()
2715 }
2716}
2717
2718#[derive(Debug, Error, Clone)]
2720pub enum Error {
2721 #[error("Fidl validation failed: {}", err)]
2722 Validate {
2723 #[source]
2724 err: cm_fidl_validator::error::ErrorList,
2725 },
2726 #[error("Invalid capability path: {}", raw)]
2727 InvalidCapabilityPath { raw: String },
2728 #[error("Invalid capability type name: {}", raw)]
2729 ParseCapabilityTypeName { raw: String },
2730}
2731
2732#[cfg(test)]
2733mod tests {
2734 use super::*;
2735 use difference::Changeset;
2736 use fidl_fuchsia_component_decl as fdecl;
2737
2738 fn offer_source_static_child(name: &str) -> OfferSource {
2739 OfferSource::Child(ChildRef { name: name.parse().unwrap(), collection: None })
2740 }
2741
2742 fn offer_target_static_child(name: &str) -> OfferTarget {
2743 OfferTarget::Child(ChildRef { name: name.parse().unwrap(), collection: None })
2744 }
2745
2746 macro_rules! test_try_from_decl {
2747 (
2748 $(
2749 $test_name:ident => {
2750 input = $input:expr,
2751 result = $result:expr,
2752 },
2753 )+
2754 ) => {
2755 $(
2756 #[test]
2757 fn $test_name() {
2758 {
2759 let res = ComponentDecl::try_from($input).expect("try_from failed");
2760 if res != $result {
2761 let a = format!("{:#?}", res);
2762 let e = format!("{:#?}", $result);
2763 panic!("Conversion from fidl to cm_rust did not yield expected result:\n{}", Changeset::new(&a, &e, "\n"));
2764 }
2765 }
2766 {
2767 let res = fdecl::Component::try_from($result).expect("try_from failed");
2768 if res != $input {
2769 let a = format!("{:#?}", res);
2770 let e = format!("{:#?}", $input);
2771 panic!("Conversion from cm_rust to fidl did not yield expected result:\n{}", Changeset::new(&a, &e, "\n"));
2772 }
2773 }
2774 }
2775 )+
2776 }
2777 }
2778
2779 macro_rules! test_fidl_into_and_from {
2780 (
2781 $(
2782 $test_name:ident => {
2783 input = $input:expr,
2784 input_type = $input_type:ty,
2785 result = $result:expr,
2786 result_type = $result_type:ty,
2787 },
2788 )+
2789 ) => {
2790 $(
2791 #[test]
2792 fn $test_name() {
2793 {
2794 let res: Vec<$result_type> =
2795 $input.into_iter().map(|e| e.fidl_into_native()).collect();
2796 assert_eq!(res, $result);
2797 }
2798 {
2799 let res: Vec<$input_type> =
2800 $result.into_iter().map(|e| e.native_into_fidl()).collect();
2801 assert_eq!(res, $input);
2802 }
2803 }
2804 )+
2805 }
2806 }
2807
2808 macro_rules! test_fidl_into {
2809 (
2810 $(
2811 $test_name:ident => {
2812 input = $input:expr,
2813 result = $result:expr,
2814 },
2815 )+
2816 ) => {
2817 $(
2818 #[test]
2819 fn $test_name() {
2820 test_fidl_into_helper($input, $result);
2821 }
2822 )+
2823 }
2824 }
2825
2826 fn test_fidl_into_helper<T, U>(input: T, expected_res: U)
2827 where
2828 T: FidlIntoNative<U>,
2829 U: std::cmp::PartialEq + std::fmt::Debug,
2830 {
2831 let res: U = input.fidl_into_native();
2832 assert_eq!(res, expected_res);
2833 }
2834
2835 test_try_from_decl! {
2836 try_from_empty => {
2837 input = fdecl::Component {
2838 program: None,
2839 uses: None,
2840 exposes: None,
2841 offers: None,
2842 capabilities: None,
2843 children: None,
2844 collections: None,
2845 facets: None,
2846 environments: None,
2847 ..Default::default()
2848 },
2849 result = ComponentDecl {
2850 program: None,
2851 uses: vec![],
2852 exposes: vec![],
2853 offers: vec![],
2854 capabilities: vec![],
2855 children: vec![],
2856 collections: vec![],
2857 facets: None,
2858 environments: vec![],
2859 config: None,
2860 },
2861 },
2862 try_from_all => {
2863 input = fdecl::Component {
2864 program: Some(fdecl::Program {
2865 runner: Some("elf".to_string()),
2866 info: Some(fdata::Dictionary {
2867 entries: Some(vec![
2868 fdata::DictionaryEntry {
2869 key: "args".to_string(),
2870 value: Some(Box::new(fdata::DictionaryValue::StrVec(vec!["foo".to_string(), "bar".to_string()]))),
2871 },
2872 fdata::DictionaryEntry {
2873 key: "binary".to_string(),
2874 value: Some(Box::new(fdata::DictionaryValue::Str("bin/app".to_string()))),
2875 },
2876 ]),
2877 ..Default::default()
2878 }),
2879 ..Default::default()
2880 }),
2881 uses: Some(vec![
2882 fdecl::Use::Service(fdecl::UseService {
2883 dependency_type: Some(fdecl::DependencyType::Strong),
2884 source: Some(fdecl::Ref::Parent(fdecl::ParentRef {})),
2885 source_name: Some("netstack".to_string()),
2886 source_dictionary: Some("in/dict".to_string()),
2887 target_path: Some("/svc/mynetstack".to_string()),
2888 availability: Some(fdecl::Availability::Required),
2889 ..Default::default()
2890 }),
2891 fdecl::Use::Protocol(fdecl::UseProtocol {
2892 dependency_type: Some(fdecl::DependencyType::Strong),
2893 source: Some(fdecl::Ref::Parent(fdecl::ParentRef {})),
2894 source_name: Some("legacy_netstack".to_string()),
2895 source_dictionary: Some("in/dict".to_string()),
2896 target_path: Some("/svc/legacy_mynetstack".to_string()),
2897 availability: Some(fdecl::Availability::Optional),
2898 ..Default::default()
2899 }),
2900 fdecl::Use::Protocol(fdecl::UseProtocol {
2901 dependency_type: Some(fdecl::DependencyType::Strong),
2902 source: Some(fdecl::Ref::Child(fdecl::ChildRef { name: "echo".to_string(), collection: None})),
2903 source_name: Some("echo_service".to_string()),
2904 source_dictionary: Some("in/dict".to_string()),
2905 target_path: Some("/svc/echo_service".to_string()),
2906 availability: Some(fdecl::Availability::Required),
2907 ..Default::default()
2908 }),
2909 fdecl::Use::Directory(fdecl::UseDirectory {
2910 dependency_type: Some(fdecl::DependencyType::Strong),
2911 source: Some(fdecl::Ref::Self_(fdecl::SelfRef {})),
2912 source_name: Some("dir".to_string()),
2913 source_dictionary: Some("dict1/me".to_string()),
2914 target_path: Some("/data".to_string()),
2915 rights: Some(fio::Operations::CONNECT),
2916 subdir: Some("foo/bar".to_string()),
2917 availability: Some(fdecl::Availability::Required),
2918 ..Default::default()
2919 }),
2920 fdecl::Use::Storage(fdecl::UseStorage {
2921 source_name: Some("cache".to_string()),
2922 target_path: Some("/cache".to_string()),
2923 availability: Some(fdecl::Availability::Required),
2924 ..Default::default()
2925 }),
2926 fdecl::Use::Storage(fdecl::UseStorage {
2927 source_name: Some("temp".to_string()),
2928 target_path: Some("/temp".to_string()),
2929 availability: Some(fdecl::Availability::Optional),
2930 ..Default::default()
2931 }),
2932 fdecl::Use::EventStream(fdecl::UseEventStream {
2933 source: Some(fdecl::Ref::Child(fdecl::ChildRef {
2934 collection: None,
2935 name: "netstack".to_string(),
2936 })),
2937 source_name: Some("stopped".to_string()),
2938 scope: Some(vec![
2939 fdecl::Ref::Child(fdecl::ChildRef {
2940 collection: None,
2941 name:"a".to_string(),
2942 }), fdecl::Ref::Collection(fdecl::CollectionRef {
2943 name:"b".to_string(),
2944 })]),
2945 target_path: Some("/svc/test".to_string()),
2946 availability: Some(fdecl::Availability::Optional),
2947 ..Default::default()
2948 }),
2949 fdecl::Use::Runner(fdecl::UseRunner {
2950 source: Some(fdecl::Ref::Environment(fdecl::EnvironmentRef {})),
2951 source_name: Some("elf".to_string()),
2952 source_dictionary: None,
2953 ..Default::default()
2954 }),
2955 fdecl::Use::Config(fdecl::UseConfiguration {
2956 source: Some(fdecl::Ref::Parent(fdecl::ParentRef)),
2957 source_name: Some("fuchsia.config.MyConfig".to_string()),
2958 target_name: Some("my_config".to_string()),
2959 availability: Some(fdecl::Availability::Required),
2960 type_: Some(fdecl::ConfigType{
2961 layout: fdecl::ConfigTypeLayout::Bool,
2962 parameters: Some(Vec::new()),
2963 constraints: Vec::new(),
2964 }),
2965 ..Default::default()
2966 }),
2967 ]),
2968 exposes: Some(vec![
2969 fdecl::Expose::Protocol(fdecl::ExposeProtocol {
2970 source: Some(fdecl::Ref::Child(fdecl::ChildRef {
2971 name: "netstack".to_string(),
2972 collection: None,
2973 })),
2974 source_name: Some("legacy_netstack".to_string()),
2975 source_dictionary: Some("in/dict".to_string()),
2976 target_name: Some("legacy_mynetstack".to_string()),
2977 target: Some(fdecl::Ref::Parent(fdecl::ParentRef {})),
2978 availability: Some(fdecl::Availability::Required),
2979 ..Default::default()
2980 }),
2981 fdecl::Expose::Directory(fdecl::ExposeDirectory {
2982 source: Some(fdecl::Ref::Child(fdecl::ChildRef {
2983 name: "netstack".to_string(),
2984 collection: None,
2985 })),
2986 source_name: Some("dir".to_string()),
2987 source_dictionary: Some("in/dict".to_string()),
2988 target_name: Some("data".to_string()),
2989 target: Some(fdecl::Ref::Parent(fdecl::ParentRef {})),
2990 rights: Some(fio::Operations::CONNECT),
2991 subdir: Some("foo/bar".to_string()),
2992 availability: Some(fdecl::Availability::Optional),
2993 ..Default::default()
2994 }),
2995 fdecl::Expose::Runner(fdecl::ExposeRunner {
2996 source: Some(fdecl::Ref::Child(fdecl::ChildRef {
2997 name: "netstack".to_string(),
2998 collection: None,
2999 })),
3000 source_name: Some("elf".to_string()),
3001 source_dictionary: Some("in/dict".to_string()),
3002 target: Some(fdecl::Ref::Parent(fdecl::ParentRef {})),
3003 target_name: Some("elf".to_string()),
3004 ..Default::default()
3005 }),
3006 fdecl::Expose::Resolver(fdecl::ExposeResolver{
3007 source: Some(fdecl::Ref::Child(fdecl::ChildRef {
3008 name: "netstack".to_string(),
3009 collection: None,
3010 })),
3011 source_name: Some("pkg".to_string()),
3012 source_dictionary: Some("in/dict".to_string()),
3013 target: Some(fdecl::Ref::Parent(fdecl::ParentRef{})),
3014 target_name: Some("pkg".to_string()),
3015 ..Default::default()
3016 }),
3017 fdecl::Expose::Service(fdecl::ExposeService {
3018 source: Some(fdecl::Ref::Child(fdecl::ChildRef {
3019 name: "netstack".to_string(),
3020 collection: None,
3021 })),
3022 source_name: Some("netstack1".to_string()),
3023 source_dictionary: Some("in/dict".to_string()),
3024 target_name: Some("mynetstack".to_string()),
3025 target: Some(fdecl::Ref::Parent(fdecl::ParentRef {})),
3026 availability: Some(fdecl::Availability::Required),
3027 ..Default::default()
3028 }),
3029 fdecl::Expose::Service(fdecl::ExposeService {
3030 source: Some(fdecl::Ref::Collection(fdecl::CollectionRef {
3031 name: "modular".to_string(),
3032 })),
3033 source_name: Some("netstack2".to_string()),
3034 source_dictionary: None,
3035 target_name: Some("mynetstack".to_string()),
3036 target: Some(fdecl::Ref::Parent(fdecl::ParentRef {})),
3037 availability: Some(fdecl::Availability::Required),
3038 ..Default::default()
3039 }),
3040 fdecl::Expose::Dictionary(fdecl::ExposeDictionary {
3041 source: Some(fdecl::Ref::Child(fdecl::ChildRef {
3042 name: "netstack".to_string(),
3043 collection: None,
3044 })),
3045 source_name: Some("bundle".to_string()),
3046 source_dictionary: Some("in/dict".to_string()),
3047 target_name: Some("mybundle".to_string()),
3048 target: Some(fdecl::Ref::Parent(fdecl::ParentRef {})),
3049 availability: Some(fdecl::Availability::Required),
3050 ..Default::default()
3051 }),
3052 ]),
3053 offers: Some(vec![
3054 fdecl::Offer::Protocol(fdecl::OfferProtocol {
3055 source: Some(fdecl::Ref::Parent(fdecl::ParentRef {})),
3056 source_name: Some("legacy_netstack".to_string()),
3057 source_dictionary: Some("in/dict".to_string()),
3058 target: Some(fdecl::Ref::Child(
3059 fdecl::ChildRef {
3060 name: "echo".to_string(),
3061 collection: None,
3062 }
3063 )),
3064 target_name: Some("legacy_mynetstack".to_string()),
3065 dependency_type: Some(fdecl::DependencyType::Weak),
3066 availability: Some(fdecl::Availability::Required),
3067 ..Default::default()
3068 }),
3069 fdecl::Offer::Directory(fdecl::OfferDirectory {
3070 source: Some(fdecl::Ref::Parent(fdecl::ParentRef {})),
3071 source_name: Some("dir".to_string()),
3072 source_dictionary: Some("in/dict".to_string()),
3073 target: Some(fdecl::Ref::Collection(
3074 fdecl::CollectionRef { name: "modular".to_string() }
3075 )),
3076 target_name: Some("data".to_string()),
3077 rights: Some(fio::Operations::CONNECT),
3078 subdir: None,
3079 dependency_type: Some(fdecl::DependencyType::Strong),
3080 availability: Some(fdecl::Availability::Optional),
3081 ..Default::default()
3082 }),
3083 fdecl::Offer::Storage(fdecl::OfferStorage {
3084 source_name: Some("cache".to_string()),
3085 source: Some(fdecl::Ref::Self_(fdecl::SelfRef {})),
3086 target: Some(fdecl::Ref::Collection(
3087 fdecl::CollectionRef { name: "modular".to_string() }
3088 )),
3089 target_name: Some("cache".to_string()),
3090 availability: Some(fdecl::Availability::Required),
3091 ..Default::default()
3092 }),
3093 fdecl::Offer::Runner(fdecl::OfferRunner {
3094 source: Some(fdecl::Ref::Parent(fdecl::ParentRef {})),
3095 source_name: Some("elf".to_string()),
3096 source_dictionary: Some("in/dict".to_string()),
3097 target: Some(fdecl::Ref::Child(
3098 fdecl::ChildRef {
3099 name: "echo".to_string(),
3100 collection: None,
3101 }
3102 )),
3103 target_name: Some("elf2".to_string()),
3104 ..Default::default()
3105 }),
3106 fdecl::Offer::Resolver(fdecl::OfferResolver{
3107 source: Some(fdecl::Ref::Parent(fdecl::ParentRef{})),
3108 source_name: Some("pkg".to_string()),
3109 source_dictionary: Some("in/dict".to_string()),
3110 target: Some(fdecl::Ref::Child(
3111 fdecl::ChildRef {
3112 name: "echo".to_string(),
3113 collection: None,
3114 }
3115 )),
3116 target_name: Some("pkg".to_string()),
3117 ..Default::default()
3118 }),
3119 fdecl::Offer::Service(fdecl::OfferService {
3120 source: Some(fdecl::Ref::Parent(fdecl::ParentRef {})),
3121 source_name: Some("netstack1".to_string()),
3122 source_dictionary: Some("in/dict".to_string()),
3123 target: Some(fdecl::Ref::Child(
3124 fdecl::ChildRef {
3125 name: "echo".to_string(),
3126 collection: None,
3127 }
3128 )),
3129 target_name: Some("mynetstack1".to_string()),
3130 availability: Some(fdecl::Availability::Required),
3131 dependency_type: Some(fdecl::DependencyType::Strong),
3132 ..Default::default()
3133 }),
3134 fdecl::Offer::Service(fdecl::OfferService {
3135 source: Some(fdecl::Ref::Parent(fdecl::ParentRef {})),
3136 source_name: Some("netstack2".to_string()),
3137 source_dictionary: None,
3138 target: Some(fdecl::Ref::Child(
3139 fdecl::ChildRef {
3140 name: "echo".to_string(),
3141 collection: None,
3142 }
3143 )),
3144 target_name: Some("mynetstack2".to_string()),
3145 availability: Some(fdecl::Availability::Optional),
3146 dependency_type: Some(fdecl::DependencyType::Strong),
3147 ..Default::default()
3148 }),
3149 fdecl::Offer::Service(fdecl::OfferService {
3150 source: Some(fdecl::Ref::Parent(fdecl::ParentRef {})),
3151 source_name: Some("netstack3".to_string()),
3152 source_dictionary: None,
3153 target: Some(fdecl::Ref::Child(
3154 fdecl::ChildRef {
3155 name: "echo".to_string(),
3156 collection: None,
3157 }
3158 )),
3159 target_name: Some("mynetstack3".to_string()),
3160 source_instance_filter: Some(vec!["allowedinstance".to_string()]),
3161 renamed_instances: Some(vec![fdecl::NameMapping{source_name: "default".to_string(), target_name: "allowedinstance".to_string()}]),
3162 availability: Some(fdecl::Availability::Required),
3163 dependency_type: Some(fdecl::DependencyType::Strong),
3164 ..Default::default()
3165 }),
3166 fdecl::Offer::Dictionary(fdecl::OfferDictionary {
3167 source: Some(fdecl::Ref::Parent(fdecl::ParentRef {})),
3168 source_name: Some("bundle".to_string()),
3169 source_dictionary: Some("in/dict".to_string()),
3170 target: Some(fdecl::Ref::Child(
3171 fdecl::ChildRef {
3172 name: "echo".to_string(),
3173 collection: None,
3174 }
3175 )),
3176 target_name: Some("mybundle".to_string()),
3177 dependency_type: Some(fdecl::DependencyType::Weak),
3178 availability: Some(fdecl::Availability::Required),
3179 ..Default::default()
3180 }),
3181 ]),
3182 capabilities: Some(vec![
3183 fdecl::Capability::Service(fdecl::Service {
3184 name: Some("netstack".to_string()),
3185 source_path: Some("/netstack".to_string()),
3186 ..Default::default()
3187 }),
3188 fdecl::Capability::Protocol(fdecl::Protocol {
3189 name: Some("netstack2".to_string()),
3190 source_path: Some("/netstack2".to_string()),
3191 delivery: Some(fdecl::DeliveryType::Immediate),
3192 ..Default::default()
3193 }),
3194 fdecl::Capability::Directory(fdecl::Directory {
3195 name: Some("data".to_string()),
3196 source_path: Some("/data".to_string()),
3197 rights: Some(fio::Operations::CONNECT),
3198 ..Default::default()
3199 }),
3200 fdecl::Capability::Storage(fdecl::Storage {
3201 name: Some("cache".to_string()),
3202 backing_dir: Some("data".to_string()),
3203 source: Some(fdecl::Ref::Parent(fdecl::ParentRef {})),
3204 subdir: Some("cache".to_string()),
3205 storage_id: Some(fdecl::StorageId::StaticInstanceId),
3206 ..Default::default()
3207 }),
3208 fdecl::Capability::Runner(fdecl::Runner {
3209 name: Some("elf".to_string()),
3210 source_path: Some("/elf".to_string()),
3211 ..Default::default()
3212 }),
3213 fdecl::Capability::Resolver(fdecl::Resolver {
3214 name: Some("pkg".to_string()),
3215 source_path: Some("/pkg_resolver".to_string()),
3216 ..Default::default()
3217 }),
3218 fdecl::Capability::Dictionary(fdecl::Dictionary {
3219 name: Some("dict1".to_string()),
3220 ..Default::default()
3221 }),
3222 fdecl::Capability::Dictionary(fdecl::Dictionary {
3223 name: Some("dict2".to_string()),
3224 source_path: Some("/in/other".to_string()),
3225 ..Default::default()
3226 }),
3227 ]),
3228 children: Some(vec![
3229 fdecl::Child {
3230 name: Some("netstack".to_string()),
3231 url: Some("fuchsia-pkg://fuchsia.com/netstack#meta/netstack.cm"
3232 .to_string()),
3233 startup: Some(fdecl::StartupMode::Lazy),
3234 on_terminate: None,
3235 environment: None,
3236 ..Default::default()
3237 },
3238 fdecl::Child {
3239 name: Some("gtest".to_string()),
3240 url: Some("fuchsia-pkg://fuchsia.com/gtest#meta/gtest.cm".to_string()),
3241 startup: Some(fdecl::StartupMode::Lazy),
3242 on_terminate: Some(fdecl::OnTerminate::None),
3243 environment: None,
3244 ..Default::default()
3245 },
3246 fdecl::Child {
3247 name: Some("echo".to_string()),
3248 url: Some("fuchsia-pkg://fuchsia.com/echo#meta/echo.cm"
3249 .to_string()),
3250 startup: Some(fdecl::StartupMode::Eager),
3251 on_terminate: Some(fdecl::OnTerminate::Reboot),
3252 environment: Some("test_env".to_string()),
3253 ..Default::default()
3254 },
3255 ]),
3256 collections: Some(vec![
3257 fdecl::Collection {
3258 name: Some("modular".to_string()),
3259 durability: Some(fdecl::Durability::Transient),
3260 environment: None,
3261 allowed_offers: Some(fdecl::AllowedOffers::StaticOnly),
3262 allow_long_names: Some(true),
3263 persistent_storage: None,
3264 ..Default::default()
3265 },
3266 fdecl::Collection {
3267 name: Some("tests".to_string()),
3268 durability: Some(fdecl::Durability::Transient),
3269 environment: Some("test_env".to_string()),
3270 allowed_offers: Some(fdecl::AllowedOffers::StaticAndDynamic),
3271 allow_long_names: Some(true),
3272 persistent_storage: Some(true),
3273 ..Default::default()
3274 },
3275 ]),
3276 facets: Some(fdata::Dictionary {
3277 entries: Some(vec![
3278 fdata::DictionaryEntry {
3279 key: "author".to_string(),
3280 value: Some(Box::new(fdata::DictionaryValue::Str("Fuchsia".to_string()))),
3281 },
3282 ]),
3283 ..Default::default()
3284 }),
3285 environments: Some(vec![
3286 fdecl::Environment {
3287 name: Some("test_env".to_string()),
3288 extends: Some(fdecl::EnvironmentExtends::Realm),
3289 runners: Some(vec![
3290 fdecl::RunnerRegistration {
3291 source_name: Some("runner".to_string()),
3292 source: Some(fdecl::Ref::Child(fdecl::ChildRef {
3293 name: "gtest".to_string(),
3294 collection: None,
3295 })),
3296 target_name: Some("gtest-runner".to_string()),
3297 ..Default::default()
3298 }
3299 ]),
3300 resolvers: Some(vec![
3301 fdecl::ResolverRegistration {
3302 resolver: Some("pkg_resolver".to_string()),
3303 source: Some(fdecl::Ref::Parent(fdecl::ParentRef{})),
3304 scheme: Some("fuchsia-pkg".to_string()),
3305 ..Default::default()
3306 }
3307 ]),
3308 debug_capabilities: Some(vec![
3309 fdecl::DebugRegistration::Protocol(fdecl::DebugProtocolRegistration {
3310 source_name: Some("some_protocol".to_string()),
3311 source: Some(fdecl::Ref::Child(fdecl::ChildRef {
3312 name: "gtest".to_string(),
3313 collection: None,
3314 })),
3315 target_name: Some("some_protocol".to_string()),
3316 ..Default::default()
3317 })
3318 ]),
3319 stop_timeout_ms: Some(4567),
3320 ..Default::default()
3321 }
3322 ]),
3323 config: Some(fdecl::ConfigSchema{
3324 fields: Some(vec![
3325 fdecl::ConfigField {
3326 key: Some("enable_logging".to_string()),
3327 type_: Some(fdecl::ConfigType {
3328 layout: fdecl::ConfigTypeLayout::Bool,
3329 parameters: Some(vec![]),
3330 constraints: vec![],
3331 }),
3332 mutability: Some(Default::default()),
3333 ..Default::default()
3334 }
3335 ]),
3336 checksum: Some(fdecl::ConfigChecksum::Sha256([
3337 0x64, 0x49, 0x9E, 0x75, 0xF3, 0x37, 0x69, 0x88, 0x74, 0x3B, 0x38, 0x16,
3338 0xCD, 0x14, 0x70, 0x9F, 0x3D, 0x4A, 0xD3, 0xE2, 0x24, 0x9A, 0x1A, 0x34,
3339 0x80, 0xB4, 0x9E, 0xB9, 0x63, 0x57, 0xD6, 0xED,
3340 ])),
3341 value_source: Some(
3342 fdecl::ConfigValueSource::PackagePath("fake.cvf".to_string())
3343 ),
3344 ..Default::default()
3345 }),
3346 ..Default::default()
3347 },
3348 result = {
3349 ComponentDecl {
3350 program: Some(ProgramDecl {
3351 runner: Some("elf".parse().unwrap()),
3352 info: fdata::Dictionary {
3353 entries: Some(vec![
3354 fdata::DictionaryEntry {
3355 key: "args".to_string(),
3356 value: Some(Box::new(fdata::DictionaryValue::StrVec(vec!["foo".to_string(), "bar".to_string()]))),
3357 },
3358 fdata::DictionaryEntry{
3359 key: "binary".to_string(),
3360 value: Some(Box::new(fdata::DictionaryValue::Str("bin/app".to_string()))),
3361 },
3362 ]),
3363 ..Default::default()
3364 },
3365 }),
3366 uses: vec![
3367 UseDecl::Service(UseServiceDecl {
3368 dependency_type: DependencyType::Strong,
3369 source: UseSource::Parent,
3370 source_name: "netstack".parse().unwrap(),
3371 source_dictionary: "in/dict".parse().unwrap(),
3372 target_path: "/svc/mynetstack".parse().unwrap(),
3373 availability: Availability::Required,
3374 }),
3375 UseDecl::Protocol(UseProtocolDecl {
3376 dependency_type: DependencyType::Strong,
3377 source: UseSource::Parent,
3378 source_name: "legacy_netstack".parse().unwrap(),
3379 source_dictionary: "in/dict".parse().unwrap(),
3380 target_path: "/svc/legacy_mynetstack".parse().unwrap(),
3381 availability: Availability::Optional,
3382 }),
3383 UseDecl::Protocol(UseProtocolDecl {
3384 dependency_type: DependencyType::Strong,
3385 source: UseSource::Child("echo".parse().unwrap()),
3386 source_name: "echo_service".parse().unwrap(),
3387 source_dictionary: "in/dict".parse().unwrap(),
3388 target_path: "/svc/echo_service".parse().unwrap(),
3389 availability: Availability::Required,
3390 }),
3391 UseDecl::Directory(UseDirectoryDecl {
3392 dependency_type: DependencyType::Strong,
3393 source: UseSource::Self_,
3394 source_name: "dir".parse().unwrap(),
3395 source_dictionary: "dict1/me".parse().unwrap(),
3396 target_path: "/data".parse().unwrap(),
3397 rights: fio::Operations::CONNECT,
3398 subdir: "foo/bar".parse().unwrap(),
3399 availability: Availability::Required,
3400 }),
3401 UseDecl::Storage(UseStorageDecl {
3402 source_name: "cache".parse().unwrap(),
3403 target_path: "/cache".parse().unwrap(),
3404 availability: Availability::Required,
3405 }),
3406 UseDecl::Storage(UseStorageDecl {
3407 source_name: "temp".parse().unwrap(),
3408 target_path: "/temp".parse().unwrap(),
3409 availability: Availability::Optional,
3410 }),
3411 UseDecl::EventStream(UseEventStreamDecl {
3412 source: UseSource::Child("netstack".parse().unwrap()),
3413 scope: Some(vec![EventScope::Child(ChildRef{ name: "a".parse().unwrap(), collection: None}), EventScope::Collection("b".parse().unwrap())]),
3414 source_name: "stopped".parse().unwrap(),
3415 target_path: "/svc/test".parse().unwrap(),
3416 filter: None,
3417 availability: Availability::Optional,
3418 }),
3419 UseDecl::Runner(UseRunnerDecl {
3420 source: UseSource::Environment,
3421 source_name: "elf".parse().unwrap(),
3422 source_dictionary: ".".parse().unwrap(),
3423 }),
3424 UseDecl::Config(UseConfigurationDecl {
3425 source: UseSource::Parent,
3426 source_name: "fuchsia.config.MyConfig".parse().unwrap(),
3427 target_name: "my_config".parse().unwrap(),
3428 availability: Availability::Required,
3429 type_: ConfigValueType::Bool,
3430 default: None,
3431 source_dictionary: ".".parse().unwrap(),
3432 }),
3433 ],
3434 exposes: vec![
3435 ExposeDecl::Protocol(ExposeProtocolDecl {
3436 source: ExposeSource::Child("netstack".parse().unwrap()),
3437 source_name: "legacy_netstack".parse().unwrap(),
3438 source_dictionary: "in/dict".parse().unwrap(),
3439 target_name: "legacy_mynetstack".parse().unwrap(),
3440 target: ExposeTarget::Parent,
3441 availability: Availability::Required,
3442 }),
3443 ExposeDecl::Directory(ExposeDirectoryDecl {
3444 source: ExposeSource::Child("netstack".parse().unwrap()),
3445 source_name: "dir".parse().unwrap(),
3446 source_dictionary: "in/dict".parse().unwrap(),
3447 target_name: "data".parse().unwrap(),
3448 target: ExposeTarget::Parent,
3449 rights: Some(fio::Operations::CONNECT),
3450 subdir: "foo/bar".parse().unwrap(),
3451 availability: Availability::Optional,
3452 }),
3453 ExposeDecl::Runner(ExposeRunnerDecl {
3454 source: ExposeSource::Child("netstack".parse().unwrap()),
3455 source_name: "elf".parse().unwrap(),
3456 source_dictionary: "in/dict".parse().unwrap(),
3457 target: ExposeTarget::Parent,
3458 target_name: "elf".parse().unwrap(),
3459 }),
3460 ExposeDecl::Resolver(ExposeResolverDecl {
3461 source: ExposeSource::Child("netstack".parse().unwrap()),
3462 source_name: "pkg".parse().unwrap(),
3463 source_dictionary: "in/dict".parse().unwrap(),
3464 target: ExposeTarget::Parent,
3465 target_name: "pkg".parse().unwrap(),
3466 }),
3467 ExposeDecl::Service(ExposeServiceDecl {
3468 source: ExposeSource::Child("netstack".parse().unwrap()),
3469 source_name: "netstack1".parse().unwrap(),
3470 source_dictionary: "in/dict".parse().unwrap(),
3471 target_name: "mynetstack".parse().unwrap(),
3472 target: ExposeTarget::Parent,
3473 availability: Availability::Required,
3474 }),
3475 ExposeDecl::Service(ExposeServiceDecl {
3476 source: ExposeSource::Collection("modular".parse().unwrap()),
3477 source_name: "netstack2".parse().unwrap(),
3478 source_dictionary: ".".parse().unwrap(),
3479 target_name: "mynetstack".parse().unwrap(),
3480 target: ExposeTarget::Parent,
3481 availability: Availability::Required,
3482 }),
3483 ExposeDecl::Dictionary(ExposeDictionaryDecl {
3484 source: ExposeSource::Child("netstack".parse().unwrap()),
3485 source_name: "bundle".parse().unwrap(),
3486 source_dictionary: "in/dict".parse().unwrap(),
3487 target_name: "mybundle".parse().unwrap(),
3488 target: ExposeTarget::Parent,
3489 availability: Availability::Required,
3490 }),
3491 ],
3492 offers: vec![
3493 OfferDecl::Protocol(OfferProtocolDecl {
3494 source: OfferSource::Parent,
3495 source_name: "legacy_netstack".parse().unwrap(),
3496 source_dictionary: "in/dict".parse().unwrap(),
3497 target: offer_target_static_child("echo"),
3498 target_name: "legacy_mynetstack".parse().unwrap(),
3499 dependency_type: DependencyType::Weak,
3500 availability: Availability::Required,
3501 }),
3502 OfferDecl::Directory(OfferDirectoryDecl {
3503 source: OfferSource::Parent,
3504 source_name: "dir".parse().unwrap(),
3505 source_dictionary: "in/dict".parse().unwrap(),
3506 target: OfferTarget::Collection("modular".parse().unwrap()),
3507 target_name: "data".parse().unwrap(),
3508 rights: Some(fio::Operations::CONNECT),
3509 subdir: ".".parse().unwrap(),
3510 dependency_type: DependencyType::Strong,
3511 availability: Availability::Optional,
3512 }),
3513 OfferDecl::Storage(OfferStorageDecl {
3514 source_name: "cache".parse().unwrap(),
3515 source: OfferSource::Self_,
3516 target: OfferTarget::Collection("modular".parse().unwrap()),
3517 target_name: "cache".parse().unwrap(),
3518 availability: Availability::Required,
3519 }),
3520 OfferDecl::Runner(OfferRunnerDecl {
3521 source: OfferSource::Parent,
3522 source_name: "elf".parse().unwrap(),
3523 source_dictionary: "in/dict".parse().unwrap(),
3524 target: offer_target_static_child("echo"),
3525 target_name: "elf2".parse().unwrap(),
3526 }),
3527 OfferDecl::Resolver(OfferResolverDecl {
3528 source: OfferSource::Parent,
3529 source_name: "pkg".parse().unwrap(),
3530 source_dictionary: "in/dict".parse().unwrap(),
3531 target: offer_target_static_child("echo"),
3532 target_name: "pkg".parse().unwrap(),
3533 }),
3534 OfferDecl::Service(OfferServiceDecl {
3535 source: OfferSource::Parent,
3536 source_name: "netstack1".parse().unwrap(),
3537 source_dictionary: "in/dict".parse().unwrap(),
3538 source_instance_filter: None,
3539 renamed_instances: None,
3540 target: offer_target_static_child("echo"),
3541 target_name: "mynetstack1".parse().unwrap(),
3542 availability: Availability::Required,
3543 dependency_type: Default::default(),
3544 }),
3545 OfferDecl::Service(OfferServiceDecl {
3546 source: OfferSource::Parent,
3547 source_name: "netstack2".parse().unwrap(),
3548 source_dictionary: ".".parse().unwrap(),
3549 source_instance_filter: None,
3550 renamed_instances: None,
3551 target: offer_target_static_child("echo"),
3552 target_name: "mynetstack2".parse().unwrap(),
3553 availability: Availability::Optional,
3554 dependency_type: Default::default(),
3555 }),
3556 OfferDecl::Service(OfferServiceDecl {
3557 source: OfferSource::Parent,
3558 source_name: "netstack3".parse().unwrap(),
3559 source_dictionary: ".".parse().unwrap(),
3560 source_instance_filter: Some(vec!["allowedinstance".parse().unwrap()]),
3561 renamed_instances: Some(vec![NameMapping{source_name: "default".parse().unwrap(), target_name: "allowedinstance".parse().unwrap()}]),
3562 target: offer_target_static_child("echo"),
3563 target_name: "mynetstack3".parse().unwrap(),
3564 availability: Availability::Required,
3565 dependency_type: Default::default(),
3566 }),
3567 OfferDecl::Dictionary(OfferDictionaryDecl {
3568 source: OfferSource::Parent,
3569 source_name: "bundle".parse().unwrap(),
3570 source_dictionary: "in/dict".parse().unwrap(),
3571 target: offer_target_static_child("echo"),
3572 target_name: "mybundle".parse().unwrap(),
3573 dependency_type: DependencyType::Weak,
3574 availability: Availability::Required,
3575 }),
3576 ],
3577 capabilities: vec![
3578 CapabilityDecl::Service(ServiceDecl {
3579 name: "netstack".parse().unwrap(),
3580 source_path: Some("/netstack".parse().unwrap()),
3581 }),
3582 CapabilityDecl::Protocol(ProtocolDecl {
3583 name: "netstack2".parse().unwrap(),
3584 source_path: Some("/netstack2".parse().unwrap()),
3585 delivery: DeliveryType::Immediate,
3586 }),
3587 CapabilityDecl::Directory(DirectoryDecl {
3588 name: "data".parse().unwrap(),
3589 source_path: Some("/data".parse().unwrap()),
3590 rights: fio::Operations::CONNECT,
3591 }),
3592 CapabilityDecl::Storage(StorageDecl {
3593 name: "cache".parse().unwrap(),
3594 backing_dir: "data".parse().unwrap(),
3595 source: StorageDirectorySource::Parent,
3596 subdir: "cache".parse().unwrap(),
3597 storage_id: fdecl::StorageId::StaticInstanceId,
3598 }),
3599 CapabilityDecl::Runner(RunnerDecl {
3600 name: "elf".parse().unwrap(),
3601 source_path: Some("/elf".parse().unwrap()),
3602 }),
3603 CapabilityDecl::Resolver(ResolverDecl {
3604 name: "pkg".parse().unwrap(),
3605 source_path: Some("/pkg_resolver".parse().unwrap()),
3606 }),
3607 CapabilityDecl::Dictionary(DictionaryDecl {
3608 name: "dict1".parse().unwrap(),
3609 source_path: None,
3610 }),
3611 CapabilityDecl::Dictionary(DictionaryDecl {
3612 name: "dict2".parse().unwrap(),
3613 source_path: Some("/in/other".parse().unwrap()),
3614 }),
3615 ],
3616 children: vec![
3617 ChildDecl {
3618 name: "netstack".parse().unwrap(),
3619 url: "fuchsia-pkg://fuchsia.com/netstack#meta/netstack.cm".parse().unwrap(),
3620 startup: fdecl::StartupMode::Lazy,
3621 on_terminate: None,
3622 environment: None,
3623 config_overrides: None,
3624 },
3625 ChildDecl {
3626 name: "gtest".parse().unwrap(),
3627 url: "fuchsia-pkg://fuchsia.com/gtest#meta/gtest.cm".parse().unwrap(),
3628 startup: fdecl::StartupMode::Lazy,
3629 on_terminate: Some(fdecl::OnTerminate::None),
3630 environment: None,
3631 config_overrides: None,
3632 },
3633 ChildDecl {
3634 name: "echo".parse().unwrap(),
3635 url: "fuchsia-pkg://fuchsia.com/echo#meta/echo.cm".parse().unwrap(),
3636 startup: fdecl::StartupMode::Eager,
3637 on_terminate: Some(fdecl::OnTerminate::Reboot),
3638 environment: Some("test_env".parse().unwrap()),
3639 config_overrides: None,
3640 },
3641 ],
3642 collections: vec![
3643 CollectionDecl {
3644 name: "modular".parse().unwrap(),
3645 durability: fdecl::Durability::Transient,
3646 environment: None,
3647 allowed_offers: cm_types::AllowedOffers::StaticOnly,
3648 allow_long_names: true,
3649 persistent_storage: None,
3650 },
3651 CollectionDecl {
3652 name: "tests".parse().unwrap(),
3653 durability: fdecl::Durability::Transient,
3654 environment: Some("test_env".parse().unwrap()),
3655 allowed_offers: cm_types::AllowedOffers::StaticAndDynamic,
3656 allow_long_names: true,
3657 persistent_storage: Some(true),
3658 },
3659 ],
3660 facets: Some(fdata::Dictionary {
3661 entries: Some(vec![
3662 fdata::DictionaryEntry {
3663 key: "author".to_string(),
3664 value: Some(Box::new(fdata::DictionaryValue::Str("Fuchsia".to_string()))),
3665 },
3666 ]),
3667 ..Default::default()
3668 }),
3669 environments: vec![
3670 EnvironmentDecl {
3671 name: "test_env".parse().unwrap(),
3672 extends: fdecl::EnvironmentExtends::Realm,
3673 runners: vec![
3674 RunnerRegistration {
3675 source_name: "runner".parse().unwrap(),
3676 source: RegistrationSource::Child("gtest".to_string()),
3677 target_name: "gtest-runner".parse().unwrap(),
3678 }
3679 ],
3680 resolvers: vec![
3681 ResolverRegistration {
3682 resolver: "pkg_resolver".parse().unwrap(),
3683 source: RegistrationSource::Parent,
3684 scheme: "fuchsia-pkg".to_string(),
3685 }
3686 ],
3687 debug_capabilities: vec![
3688 DebugRegistration::Protocol(DebugProtocolRegistration {
3689 source_name: "some_protocol".parse().unwrap(),
3690 source: RegistrationSource::Child("gtest".to_string()),
3691 target_name: "some_protocol".parse().unwrap(),
3692 })
3693 ],
3694 stop_timeout_ms: Some(4567),
3695 }
3696 ],
3697 config: Some(ConfigDecl {
3698 fields: vec![
3699 ConfigField {
3700 key: "enable_logging".to_string(),
3701 type_: ConfigValueType::Bool,
3702 mutability: ConfigMutability::default(),
3703 }
3704 ],
3705 checksum: ConfigChecksum::Sha256([
3706 0x64, 0x49, 0x9E, 0x75, 0xF3, 0x37, 0x69, 0x88, 0x74, 0x3B, 0x38, 0x16,
3707 0xCD, 0x14, 0x70, 0x9F, 0x3D, 0x4A, 0xD3, 0xE2, 0x24, 0x9A, 0x1A, 0x34,
3708 0x80, 0xB4, 0x9E, 0xB9, 0x63, 0x57, 0xD6, 0xED,
3709 ]),
3710 value_source: ConfigValueSource::PackagePath("fake.cvf".to_string())
3711 }),
3712 }
3713 },
3714 },
3715 }
3716
3717 test_fidl_into_and_from! {
3718 fidl_into_and_from_use_source => {
3719 input = vec![
3720 fdecl::Ref::Parent(fdecl::ParentRef{}),
3721 fdecl::Ref::Framework(fdecl::FrameworkRef{}),
3722 fdecl::Ref::Debug(fdecl::DebugRef{}),
3723 fdecl::Ref::Capability(fdecl::CapabilityRef {name: "capability".to_string()}),
3724 fdecl::Ref::Child(fdecl::ChildRef {
3725 name: "foo".into(),
3726 collection: None,
3727 }),
3728 fdecl::Ref::Environment(fdecl::EnvironmentRef{}),
3729 ],
3730 input_type = fdecl::Ref,
3731 result = vec![
3732 UseSource::Parent,
3733 UseSource::Framework,
3734 UseSource::Debug,
3735 UseSource::Capability("capability".parse().unwrap()),
3736 UseSource::Child("foo".parse().unwrap()),
3737 UseSource::Environment,
3738 ],
3739 result_type = UseSource,
3740 },
3741 fidl_into_and_from_expose_source => {
3742 input = vec![
3743 fdecl::Ref::Self_(fdecl::SelfRef {}),
3744 fdecl::Ref::Child(fdecl::ChildRef {
3745 name: "foo".into(),
3746 collection: None,
3747 }),
3748 fdecl::Ref::Framework(fdecl::FrameworkRef {}),
3749 fdecl::Ref::Collection(fdecl::CollectionRef { name: "foo".to_string() }),
3750 ],
3751 input_type = fdecl::Ref,
3752 result = vec![
3753 ExposeSource::Self_,
3754 ExposeSource::Child("foo".parse().unwrap()),
3755 ExposeSource::Framework,
3756 ExposeSource::Collection("foo".parse().unwrap()),
3757 ],
3758 result_type = ExposeSource,
3759 },
3760 fidl_into_and_from_offer_source => {
3761 input = vec![
3762 fdecl::Ref::Self_(fdecl::SelfRef {}),
3763 fdecl::Ref::Child(fdecl::ChildRef {
3764 name: "foo".into(),
3765 collection: None,
3766 }),
3767 fdecl::Ref::Framework(fdecl::FrameworkRef {}),
3768 fdecl::Ref::Capability(fdecl::CapabilityRef { name: "foo".to_string() }),
3769 fdecl::Ref::Parent(fdecl::ParentRef {}),
3770 fdecl::Ref::Collection(fdecl::CollectionRef { name: "foo".to_string() }),
3771 fdecl::Ref::VoidType(fdecl::VoidRef {}),
3772 ],
3773 input_type = fdecl::Ref,
3774 result = vec![
3775 OfferSource::Self_,
3776 offer_source_static_child("foo"),
3777 OfferSource::Framework,
3778 OfferSource::Capability("foo".parse().unwrap()),
3779 OfferSource::Parent,
3780 OfferSource::Collection("foo".parse().unwrap()),
3781 OfferSource::Void,
3782 ],
3783 result_type = OfferSource,
3784 },
3785 fidl_into_and_from_dictionary_source => {
3786 input = vec![
3787 fdecl::Ref::Self_(fdecl::SelfRef {}),
3788 fdecl::Ref::Child(fdecl::ChildRef {
3789 name: "foo".into(),
3790 collection: None,
3791 }),
3792 fdecl::Ref::Parent(fdecl::ParentRef {}),
3793 ],
3794 input_type = fdecl::Ref,
3795 result = vec![
3796 DictionarySource::Self_,
3797 DictionarySource::Child(ChildRef {
3798 name: "foo".parse().unwrap(),
3799 collection: None,
3800 }),
3801 DictionarySource::Parent,
3802 ],
3803 result_type = DictionarySource,
3804 },
3805
3806 fidl_into_and_from_capability_without_path => {
3807 input = vec![
3808 fdecl::Protocol {
3809 name: Some("foo_protocol".to_string()),
3810 source_path: None,
3811 delivery: Some(fdecl::DeliveryType::Immediate),
3812 ..Default::default()
3813 },
3814 ],
3815 input_type = fdecl::Protocol,
3816 result = vec![
3817 ProtocolDecl {
3818 name: "foo_protocol".parse().unwrap(),
3819 source_path: None,
3820 delivery: DeliveryType::Immediate,
3821 }
3822 ],
3823 result_type = ProtocolDecl,
3824 },
3825 fidl_into_and_from_storage_capability => {
3826 input = vec![
3827 fdecl::Storage {
3828 name: Some("minfs".to_string()),
3829 backing_dir: Some("minfs".into()),
3830 source: Some(fdecl::Ref::Child(fdecl::ChildRef {
3831 name: "foo".into(),
3832 collection: None,
3833 })),
3834 subdir: None,
3835 storage_id: Some(fdecl::StorageId::StaticInstanceIdOrMoniker),
3836 ..Default::default()
3837 },
3838 ],
3839 input_type = fdecl::Storage,
3840 result = vec![
3841 StorageDecl {
3842 name: "minfs".parse().unwrap(),
3843 backing_dir: "minfs".parse().unwrap(),
3844 source: StorageDirectorySource::Child("foo".to_string()),
3845 subdir: ".".parse().unwrap(),
3846 storage_id: fdecl::StorageId::StaticInstanceIdOrMoniker,
3847 },
3848 ],
3849 result_type = StorageDecl,
3850 },
3851 fidl_into_and_from_storage_capability_restricted => {
3852 input = vec![
3853 fdecl::Storage {
3854 name: Some("minfs".to_string()),
3855 backing_dir: Some("minfs".into()),
3856 source: Some(fdecl::Ref::Child(fdecl::ChildRef {
3857 name: "foo".into(),
3858 collection: None,
3859 })),
3860 subdir: None,
3861 storage_id: Some(fdecl::StorageId::StaticInstanceId),
3862 ..Default::default()
3863 },
3864 ],
3865 input_type = fdecl::Storage,
3866 result = vec![
3867 StorageDecl {
3868 name: "minfs".parse().unwrap(),
3869 backing_dir: "minfs".parse().unwrap(),
3870 source: StorageDirectorySource::Child("foo".to_string()),
3871 subdir: ".".parse().unwrap(),
3872 storage_id: fdecl::StorageId::StaticInstanceId,
3873 },
3874 ],
3875 result_type = StorageDecl,
3876 },
3877 }
3878
3879 test_fidl_into! {
3880 all_with_omitted_defaults => {
3881 input = fdecl::Component {
3882 program: Some(fdecl::Program {
3883 runner: Some("elf".to_string()),
3884 info: Some(fdata::Dictionary {
3885 entries: Some(vec![]),
3886 ..Default::default()
3887 }),
3888 ..Default::default()
3889 }),
3890 uses: Some(vec![]),
3891 exposes: Some(vec![]),
3892 offers: Some(vec![]),
3893 capabilities: Some(vec![]),
3894 children: Some(vec![]),
3895 collections: Some(vec![
3896 fdecl::Collection {
3897 name: Some("modular".to_string()),
3898 durability: Some(fdecl::Durability::Transient),
3899 environment: None,
3900 allowed_offers: None,
3901 allow_long_names: None,
3902 persistent_storage: None,
3903 ..Default::default()
3904 },
3905 fdecl::Collection {
3906 name: Some("tests".to_string()),
3907 durability: Some(fdecl::Durability::Transient),
3908 environment: Some("test_env".to_string()),
3909 allowed_offers: Some(fdecl::AllowedOffers::StaticOnly),
3910 allow_long_names: None,
3911 persistent_storage: Some(false),
3912 ..Default::default()
3913 },
3914 fdecl::Collection {
3915 name: Some("dyn_offers".to_string()),
3916 durability: Some(fdecl::Durability::Transient),
3917 allowed_offers: Some(fdecl::AllowedOffers::StaticAndDynamic),
3918 allow_long_names: None,
3919 persistent_storage: Some(true),
3920 ..Default::default()
3921 },
3922 fdecl::Collection {
3923 name: Some("long_child_names".to_string()),
3924 durability: Some(fdecl::Durability::Transient),
3925 allowed_offers: None,
3926 allow_long_names: Some(true),
3927 persistent_storage: None,
3928 ..Default::default()
3929 },
3930 ]),
3931 facets: Some(fdata::Dictionary{
3932 entries: Some(vec![]),
3933 ..Default::default()
3934 }),
3935 environments: Some(vec![]),
3936 ..Default::default()
3937 },
3938 result = {
3939 ComponentDecl {
3940 program: Some(ProgramDecl {
3941 runner: Some("elf".parse().unwrap()),
3942 info: fdata::Dictionary {
3943 entries: Some(vec![]),
3944 ..Default::default()
3945 },
3946 }),
3947 uses: vec![],
3948 exposes: vec![],
3949 offers: vec![],
3950 capabilities: vec![],
3951 children: vec![],
3952 collections: vec![
3953 CollectionDecl {
3954 name: "modular".parse().unwrap(),
3955 durability: fdecl::Durability::Transient,
3956 environment: None,
3957 allowed_offers: cm_types::AllowedOffers::StaticOnly,
3958 allow_long_names: false,
3959 persistent_storage: None,
3960 },
3961 CollectionDecl {
3962 name: "tests".parse().unwrap(),
3963 durability: fdecl::Durability::Transient,
3964 environment: Some("test_env".parse().unwrap()),
3965 allowed_offers: cm_types::AllowedOffers::StaticOnly,
3966 allow_long_names: false,
3967 persistent_storage: Some(false),
3968 },
3969 CollectionDecl {
3970 name: "dyn_offers".parse().unwrap(),
3971 durability: fdecl::Durability::Transient,
3972 environment: None,
3973 allowed_offers: cm_types::AllowedOffers::StaticAndDynamic,
3974 allow_long_names: false,
3975 persistent_storage: Some(true),
3976 },
3977 CollectionDecl {
3978 name: "long_child_names".parse().unwrap(),
3979 durability: fdecl::Durability::Transient,
3980 environment: None,
3981 allowed_offers: cm_types::AllowedOffers::StaticOnly,
3982 allow_long_names: true,
3983 persistent_storage: None,
3984 },
3985 ],
3986 facets: Some(fdata::Dictionary{
3987 entries: Some(vec![]),
3988 ..Default::default()
3989 }),
3990 environments: vec![],
3991 config: None,
3992 }
3993 },
3994 },
3995 }
3996
3997 #[test]
3998 fn default_expose_availability() {
3999 let source = fdecl::Ref::Self_(fdecl::SelfRef {});
4000 let source_name = "source";
4001 let target = fdecl::Ref::Parent(fdecl::ParentRef {});
4002 let target_name = "target";
4003 assert_eq!(
4004 *fdecl::ExposeService {
4005 source: Some(source.clone()),
4006 source_name: Some(source_name.into()),
4007 target: Some(target.clone()),
4008 target_name: Some(target_name.into()),
4009 availability: None,
4010 ..Default::default()
4011 }
4012 .fidl_into_native()
4013 .availability(),
4014 Availability::Required
4015 );
4016 assert_eq!(
4017 *fdecl::ExposeProtocol {
4018 source: Some(source.clone()),
4019 source_name: Some(source_name.into()),
4020 target: Some(target.clone()),
4021 target_name: Some(target_name.into()),
4022 ..Default::default()
4023 }
4024 .fidl_into_native()
4025 .availability(),
4026 Availability::Required
4027 );
4028 assert_eq!(
4029 *fdecl::ExposeDirectory {
4030 source: Some(source.clone()),
4031 source_name: Some(source_name.into()),
4032 target: Some(target.clone()),
4033 target_name: Some(target_name.into()),
4034 ..Default::default()
4035 }
4036 .fidl_into_native()
4037 .availability(),
4038 Availability::Required
4039 );
4040 assert_eq!(
4041 *fdecl::ExposeRunner {
4042 source: Some(source.clone()),
4043 source_name: Some(source_name.into()),
4044 target: Some(target.clone()),
4045 target_name: Some(target_name.into()),
4046 ..Default::default()
4047 }
4048 .fidl_into_native()
4049 .availability(),
4050 Availability::Required
4051 );
4052 assert_eq!(
4053 *fdecl::ExposeResolver {
4054 source: Some(source.clone()),
4055 source_name: Some(source_name.into()),
4056 target: Some(target.clone()),
4057 target_name: Some(target_name.into()),
4058 ..Default::default()
4059 }
4060 .fidl_into_native()
4061 .availability(),
4062 Availability::Required
4063 );
4064 assert_eq!(
4065 *fdecl::ExposeDictionary {
4066 source: Some(source.clone()),
4067 source_name: Some(source_name.into()),
4068 target: Some(target.clone()),
4069 target_name: Some(target_name.into()),
4070 ..Default::default()
4071 }
4072 .fidl_into_native()
4073 .availability(),
4074 Availability::Required
4075 );
4076 }
4077
4078 #[test]
4079 fn default_delivery_type() {
4080 assert_eq!(
4081 fdecl::Protocol {
4082 name: Some("foo".to_string()),
4083 source_path: Some("/foo".to_string()),
4084 delivery: None,
4085 ..Default::default()
4086 }
4087 .fidl_into_native()
4088 .delivery,
4089 DeliveryType::Immediate
4090 )
4091 }
4092
4093 #[test]
4094 fn on_readable_delivery_type() {
4095 assert_eq!(
4096 fdecl::Protocol {
4097 name: Some("foo".to_string()),
4098 source_path: Some("/foo".to_string()),
4099 delivery: Some(fdecl::DeliveryType::OnReadable),
4100 ..Default::default()
4101 }
4102 .fidl_into_native()
4103 .delivery,
4104 DeliveryType::OnReadable
4105 )
4106 }
4107
4108 #[test]
4109 fn config_value_matches_type() {
4110 let bool_true = ConfigValue::Single(ConfigSingleValue::Bool(true));
4111 let bool_false = ConfigValue::Single(ConfigSingleValue::Bool(false));
4112 let uint8_zero = ConfigValue::Single(ConfigSingleValue::Uint8(0));
4113 let vec_bool_true = ConfigValue::Vector(ConfigVectorValue::BoolVector(vec![true]));
4114 let vec_bool_false = ConfigValue::Vector(ConfigVectorValue::BoolVector(vec![false]));
4115
4116 assert!(bool_true.matches_type(&bool_false));
4117 assert!(vec_bool_true.matches_type(&vec_bool_false));
4118
4119 assert!(!bool_true.matches_type(&uint8_zero));
4120 assert!(!bool_true.matches_type(&vec_bool_true));
4121 }
4122}