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