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