Skip to main content

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