acton_core/actor/
agent_config.rs

1/*
2 * Copyright (c) 2024. Govcraft
3 *
4 * Licensed under either of
5 *   * Apache License, Version 2.0 (the "License");
6 *     you may not use this file except in compliance with the License.
7 *     You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
8 *   * MIT license: http://opensource.org/licenses/MIT
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the applicable License for the specific language governing permissions and
14 * limitations under that License.
15 */
16
17
18use acton_ern::{Ern, ErnParser};
19
20use crate::common::{BrokerRef, ParentRef};
21use crate::traits::AgentHandleInterface;
22
23/// Configuration parameters required to initialize a new agent.
24///
25/// This struct encapsulates the essential settings for creating an agent instance,
26/// including its unique identity, its relationship within the agent hierarchy (parent),
27/// and its connection to the system message broker.
28///
29/// The agent's identity is represented by an [`Ern`](acton_ern::Ern), which supports
30/// hierarchical naming. If a `parent` agent is specified during configuration, the
31/// final `Ern` of the new agent will be derived by appending its base `id` to the
32/// parent's `Ern`.
33#[derive(Default, Debug, Clone)]
34pub struct AgentConfig {
35    /// The unique identifier (`Ern`) for the agent.
36    /// If created under a parent, this will be the fully resolved hierarchical ID.
37    id: Ern,
38    /// Optional handle to the system message broker.
39    pub(crate) broker: Option<BrokerRef>,
40    /// Optional handle to the agent's parent (supervisor).
41    parent: Option<ParentRef>,
42}
43
44impl AgentConfig {
45    /// Creates a new `AgentConfig` instance, potentially deriving a hierarchical ID.
46    ///
47    /// This constructor configures a new agent. If a `parent` handle is provided,
48    /// the agent's final `id` (`Ern`) is constructed by appending the provided `id`
49    /// segment to the parent's `Ern`. If no `parent` is provided, the `id` is used directly.
50    ///
51    /// # Arguments
52    ///
53    /// * `id` - The base identifier (`Ern`) for the agent. If `parent` is `Some`, this
54    ///   acts as the final segment appended to the parent's ID. If `parent` is `None`,
55    ///   this becomes the agent's root ID.
56    /// * `parent` - An optional [`ParentRef`] (handle) to the supervising agent.
57    /// * `broker` - An optional [`BrokerRef`] (handle) to the system message broker.
58    ///
59    /// # Returns
60    ///
61    /// Returns a `Result` containing the configured `AgentConfig` instance.
62    ///
63    /// # Errors
64    ///
65    /// Returns an error if parsing the parent's ID string into an `Ern` fails when
66    /// constructing a hierarchical ID.
67    pub fn new(
68        id: Ern,
69        parent: Option<ParentRef>,
70        broker: Option<BrokerRef>,
71    ) -> anyhow::Result<AgentConfig> {
72        if let Some(parent_ref) = parent { // Use a different variable name to avoid shadowing
73            // Get the parent ERN
74            let parent_id = ErnParser::new(parent_ref.id().to_string()).parse()?;
75            let child_id = parent_id + id;
76            Ok(AgentConfig {
77                id: child_id,
78                broker,
79                parent: Some(parent_ref),
80            })
81        } else {
82            Ok(AgentConfig {
83                id,
84                broker,
85                parent, // parent is None here
86            })
87        }
88    }
89
90    /// Creates a new `AgentConfig` for a top-level agent with a root identifier.
91    ///
92    /// This is a convenience function for creating an `AgentConfig` for an agent
93    /// that has no parent (i.e., it's a root agent in the hierarchy). The provided
94    /// `name` is used to create a root [`Ern`](acton_ern::Ern).
95    ///
96    /// # Arguments
97    ///
98    /// * `name` - A string-like value that will be used as the root name for the agent's `Ern`.
99    ///
100    /// # Returns
101    ///
102    /// Returns a `Result` containing the new `AgentConfig` instance with no parent or broker.
103    ///
104    /// # Errors
105    ///
106    /// Returns an error if creating the root `Ern` from the provided `name` fails
107    /// (e.g., if the name is invalid according to `Ern` rules).
108    pub fn new_with_name(
109        name: impl Into<String>,
110    ) -> anyhow::Result<AgentConfig> {
111        Self::new(Ern::with_root(name.into())?, None, None)
112    }
113
114
115    /// Returns a clone of the agent's unique identifier (`Ern`).
116    #[inline]
117    pub(crate) fn id(&self) -> Ern {
118        self.id.clone()
119    }
120
121    /// Returns a reference to the optional broker handle.
122    #[inline]
123    pub(crate) fn get_broker(&self) -> &Option<BrokerRef> {
124        &self.broker
125    }
126
127    /// Returns a reference to the optional parent handle.
128    #[inline]
129    pub(crate) fn parent(&self) -> &Option<ParentRef> {
130        &self.parent
131    }
132}