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