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