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}