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