cml/types/collection.rs
1// Copyright 2025 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use crate::Error;
6use crate::types::common::*;
7use crate::types::environment::EnvironmentRef;
8pub use cm_types::{AllowedOffers, Durability, Name};
9use reference_doc::ReferenceDoc;
10use serde::{Deserialize, Serialize};
11use std::sync::Arc;
12
13#[derive(Deserialize, Debug, PartialEq, ReferenceDoc, Serialize)]
14#[serde(deny_unknown_fields)]
15#[reference_doc(fields_as = "list", top_level_doc_after_fields)]
16/// Example:
17///
18/// ```json5
19/// collections: [
20/// {
21/// name: "tests",
22/// durability: "transient",
23/// },
24/// ],
25/// ```
26pub struct Collection {
27 /// The name of the component collection, which is a string of one or
28 /// more of the following characters: `a-z`, `0-9`, `_`, `.`, `-`. The name
29 /// identifies this collection when used in a [reference](#references).
30 pub name: Name,
31
32 /// The duration of child component instances in the collection.
33 /// - `transient`: The instance exists until its parent is stopped or it is
34 /// explicitly destroyed.
35 /// - `single_run`: The instance is started when it is created, and destroyed
36 /// when it is stopped.
37 pub durability: Durability,
38
39 /// If present, the environment that will be
40 /// assigned to instances in this collection, one of
41 /// [`environments`](#environments). If omitted, instances in this collection
42 /// will inherit the same environment assigned to this component.
43 pub environment: Option<EnvironmentRef>,
44
45 /// Constraints on the dynamic offers that target the components in this collection.
46 /// Dynamic offers are specified when calling `fuchsia.component.Realm/CreateChild`.
47 /// - `static_only`: Only those specified in this `.cml` file. No dynamic offers.
48 /// This is the default.
49 /// - `static_and_dynamic`: Both static offers and those specified at runtime
50 /// with `CreateChild` are allowed.
51 pub allowed_offers: Option<AllowedOffers>,
52
53 /// Allow child names up to 1024 characters long instead of the usual 255 character limit.
54 /// Default is false.
55 pub allow_long_names: Option<bool>,
56
57 /// If set to `true`, the data in isolated storage used by dynamic child instances and
58 /// their descendants will persist after the instances are destroyed. A new child instance
59 /// created with the same name will share the same storage path as the previous instance.
60 pub persistent_storage: Option<bool>,
61}
62
63#[derive(Debug, Clone, Serialize)]
64pub struct ContextCollection {
65 pub name: ContextSpanned<Name>,
66 pub durability: ContextSpanned<Durability>,
67 pub environment: Option<ContextSpanned<EnvironmentRef>>,
68 pub allowed_offers: Option<ContextSpanned<AllowedOffers>>,
69 pub allow_long_names: Option<ContextSpanned<bool>>,
70 pub persistent_storage: Option<ContextSpanned<bool>>,
71}
72
73impl PartialEq for ContextCollection {
74 fn eq(&self, other: &Self) -> bool {
75 macro_rules! cmp {
76 ($field:ident) => {
77 match (&self.$field, &other.$field) {
78 (Some(a), Some(b)) => a.value == b.value,
79 (None, None) => true,
80 _ => false,
81 }
82 };
83 }
84
85 self.name.value == other.name.value
86 && self.durability.value == other.durability.value
87 && cmp!(environment)
88 && cmp!(allowed_offers)
89 && cmp!(allow_long_names)
90 && cmp!(persistent_storage)
91 }
92}
93
94impl Eq for ContextCollection {}
95
96impl Hydrate for Collection {
97 type Output = ContextCollection;
98
99 fn hydrate(self, file: &Arc<std::path::Path>) -> Result<Self::Output, Error> {
100 Ok(ContextCollection {
101 name: hydrate_simple(self.name, file),
102 durability: hydrate_simple(self.durability, file),
103 environment: hydrate_opt_simple(self.environment, file),
104 allowed_offers: hydrate_opt_simple(self.allowed_offers, file),
105 allow_long_names: hydrate_opt_simple(self.allow_long_names, file),
106 persistent_storage: hydrate_opt_simple(self.persistent_storage, file),
107 })
108 }
109}