Skip to main content

cml/types/
child.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::{Name, OnTerminate, StartupMode, Url};
9use reference_doc::ReferenceDoc;
10use serde::{Deserialize, Serialize};
11use std::path::PathBuf;
12use std::sync::Arc;
13
14/// Example:
15///
16/// ```json5
17/// children: [
18///     {
19///         name: "logger",
20///         url: "fuchsia-pkg://fuchsia.com/logger#logger.cm",
21///     },
22///     {
23///         name: "pkg_cache",
24///         url: "fuchsia-pkg://fuchsia.com/pkg_cache#meta/pkg_cache.cm",
25///         startup: "eager",
26///     },
27///     {
28///         name: "child",
29///         url: "#meta/child.cm",
30///     }
31/// ],
32/// ```
33///
34/// [component-url]: /docs/reference/components/url.md
35/// [doc-eager]: /docs/development/components/connect.md#eager
36/// [doc-reboot-on-terminate]: /docs/development/components/connect.md#reboot-on-terminate
37#[derive(ReferenceDoc, Deserialize, Debug, PartialEq, Serialize)]
38#[serde(deny_unknown_fields)]
39#[reference_doc(fields_as = "list", top_level_doc_after_fields)]
40pub struct Child {
41    /// The name of the child component instance, which is a string of one
42    /// or more of the following characters: `a-z`, `0-9`, `_`, `.`, `-`. The name
43    /// identifies this component when used in a [reference](#references).
44    pub name: Name,
45
46    /// The [component URL][component-url] for the child component instance.
47    pub url: Url,
48
49    /// The component instance's startup mode. One of:
50    /// - `lazy` _(default)_: Start the component instance only if another
51    ///     component instance binds to it.
52    /// - [`eager`][doc-eager]: Start the component instance as soon as its parent
53    ///     starts.
54    #[serde(default)]
55    #[serde(skip_serializing_if = "StartupMode::is_lazy")]
56    pub startup: StartupMode,
57
58    /// Determines the fault recovery policy to apply if this component terminates.
59    /// - `none` _(default)_: Do nothing.
60    /// - `reboot`: Gracefully reboot the system if the component terminates for
61    ///     any reason other than graceful exit. This is a special feature for use only by a narrow
62    ///     set of components; see [Termination policies][doc-reboot-on-terminate] for more
63    ///     information.
64    #[serde(skip_serializing_if = "Option::is_none")]
65    pub on_terminate: Option<OnTerminate>,
66
67    /// If present, the name of the environment to be assigned to the child component instance, one
68    /// of [`environments`](#environments). If omitted, the child will inherit the same environment
69    /// assigned to this component.
70    #[serde(skip_serializing_if = "Option::is_none")]
71    pub environment: Option<EnvironmentRef>,
72}
73
74fn is_lazy_spanned(mode: &ContextSpanned<StartupMode>) -> bool {
75    mode.value.is_lazy()
76}
77
78#[derive(Debug, Clone, Serialize)]
79pub struct ContextChild {
80    pub name: ContextSpanned<Name>,
81    pub url: ContextSpanned<Url>,
82    #[serde(skip_serializing_if = "is_lazy_spanned")]
83    pub startup: ContextSpanned<StartupMode>,
84    #[serde(skip_serializing_if = "Option::is_none")]
85    pub on_terminate: Option<ContextSpanned<OnTerminate>>,
86    #[serde(skip_serializing_if = "Option::is_none")]
87    pub environment: Option<ContextSpanned<EnvironmentRef>>,
88}
89
90impl PartialEq for ContextChild {
91    fn eq(&self, other: &Self) -> bool {
92        self.name.value == other.name.value
93    }
94}
95impl Eq for ContextChild {}
96
97impl Hydrate for Child {
98    type Output = ContextChild;
99
100    fn hydrate(self, file: &Arc<PathBuf>) -> Result<Self::Output, Error> {
101        Ok(ContextChild {
102            name: hydrate_simple(self.name, file),
103            url: hydrate_simple(self.url, file),
104            startup: hydrate_simple(self.startup, file),
105            on_terminate: hydrate_opt_simple(self.on_terminate, file),
106            environment: hydrate_opt_simple(self.environment, file),
107        })
108    }
109}