actr_cli/core/
container.rs1use anyhow::Result;
6use std::collections::HashMap;
7use std::sync::Arc;
8
9use super::components::*;
10use super::pipelines::*;
11
12#[derive(Debug, Clone, Hash, PartialEq, Eq)]
14pub enum ComponentType {
15 ConfigManager,
16 DependencyResolver,
17 ServiceDiscovery,
18 NetworkValidator,
19 FingerprintValidator,
20 ProtoProcessor,
21 CacheManager,
22 UserInterface,
23}
24
25pub struct ServiceContainer {
27 config_manager: Option<Arc<dyn ConfigManager>>,
28 dependency_resolver: Option<Arc<dyn DependencyResolver>>,
29 service_discovery: Option<Arc<dyn ServiceDiscovery>>,
30 network_validator: Option<Arc<dyn NetworkValidator>>,
31 fingerprint_validator: Option<Arc<dyn FingerprintValidator>>,
32 proto_processor: Option<Arc<dyn ProtoProcessor>>,
33 cache_manager: Option<Arc<dyn CacheManager>>,
34 user_interface: Option<Arc<dyn UserInterface>>,
35
36 validation_pipeline: Option<Arc<ValidationPipeline>>,
38 install_pipeline: Option<Arc<InstallPipeline>>,
39 generation_pipeline: Option<Arc<GenerationPipeline>>,
40}
41
42impl ServiceContainer {
43 pub fn new() -> Self {
45 Self {
46 config_manager: None,
47 dependency_resolver: None,
48 service_discovery: None,
49 network_validator: None,
50 fingerprint_validator: None,
51 proto_processor: None,
52 cache_manager: None,
53 user_interface: None,
54 validation_pipeline: None,
55 install_pipeline: None,
56 generation_pipeline: None,
57 }
58 }
59
60 pub fn register_config_manager(mut self, component: Arc<dyn ConfigManager>) -> Self {
62 self.config_manager = Some(component);
63 self
64 }
65
66 pub fn register_dependency_resolver(mut self, component: Arc<dyn DependencyResolver>) -> Self {
67 self.dependency_resolver = Some(component);
68 self
69 }
70
71 pub fn register_service_discovery(mut self, component: Arc<dyn ServiceDiscovery>) -> Self {
72 self.service_discovery = Some(component);
73 self
74 }
75
76 pub fn register_network_validator(mut self, component: Arc<dyn NetworkValidator>) -> Self {
77 self.network_validator = Some(component);
78 self
79 }
80
81 pub fn register_fingerprint_validator(
82 mut self,
83 component: Arc<dyn FingerprintValidator>,
84 ) -> Self {
85 self.fingerprint_validator = Some(component);
86 self
87 }
88
89 pub fn register_proto_processor(mut self, component: Arc<dyn ProtoProcessor>) -> Self {
90 self.proto_processor = Some(component);
91 self
92 }
93
94 pub fn register_cache_manager(mut self, component: Arc<dyn CacheManager>) -> Self {
95 self.cache_manager = Some(component);
96 self
97 }
98
99 pub fn register_user_interface(mut self, component: Arc<dyn UserInterface>) -> Self {
100 self.user_interface = Some(component);
101 self
102 }
103
104 pub fn get_config_manager(&self) -> Result<Arc<dyn ConfigManager>> {
106 self.config_manager
107 .clone()
108 .ok_or_else(|| anyhow::anyhow!("ConfigManager not registered"))
109 }
110
111 pub fn get_dependency_resolver(&self) -> Result<Arc<dyn DependencyResolver>> {
112 self.dependency_resolver
113 .clone()
114 .ok_or_else(|| anyhow::anyhow!("DependencyResolver not registered"))
115 }
116
117 pub fn get_service_discovery(&self) -> Result<Arc<dyn ServiceDiscovery>> {
118 self.service_discovery
119 .clone()
120 .ok_or_else(|| anyhow::anyhow!("ServiceDiscovery not registered"))
121 }
122
123 pub fn get_network_validator(&self) -> Result<Arc<dyn NetworkValidator>> {
124 self.network_validator
125 .clone()
126 .ok_or_else(|| anyhow::anyhow!("NetworkValidator not registered"))
127 }
128
129 pub fn get_fingerprint_validator(&self) -> Result<Arc<dyn FingerprintValidator>> {
130 self.fingerprint_validator
131 .clone()
132 .ok_or_else(|| anyhow::anyhow!("FingerprintValidator not registered"))
133 }
134
135 pub fn get_proto_processor(&self) -> Result<Arc<dyn ProtoProcessor>> {
136 self.proto_processor
137 .clone()
138 .ok_or_else(|| anyhow::anyhow!("ProtoProcessor not registered"))
139 }
140
141 pub fn get_cache_manager(&self) -> Result<Arc<dyn CacheManager>> {
142 self.cache_manager
143 .clone()
144 .ok_or_else(|| anyhow::anyhow!("CacheManager not registered"))
145 }
146
147 pub fn get_user_interface(&self) -> Result<Arc<dyn UserInterface>> {
148 self.user_interface
149 .clone()
150 .ok_or_else(|| anyhow::anyhow!("UserInterface not registered"))
151 }
152
153 pub fn get_validation_pipeline(&mut self) -> Result<Arc<ValidationPipeline>> {
155 if self.validation_pipeline.is_none() {
156 let pipeline = ValidationPipeline::new(
157 self.get_config_manager()?,
158 self.get_dependency_resolver()?,
159 self.get_service_discovery()?,
160 self.get_network_validator()?,
161 self.get_fingerprint_validator()?,
162 );
163 self.validation_pipeline = Some(Arc::new(pipeline));
164 }
165
166 Ok(self.validation_pipeline.clone().unwrap())
167 }
168
169 pub fn get_install_pipeline(&mut self) -> Result<Arc<InstallPipeline>> {
171 if self.install_pipeline.is_none() {
172 let validation_pipeline = (*self.get_validation_pipeline()?).clone();
173 let pipeline = InstallPipeline::new(
174 validation_pipeline,
175 self.get_config_manager()?,
176 self.get_cache_manager()?,
177 self.get_proto_processor()?,
178 );
179 self.install_pipeline = Some(Arc::new(pipeline));
180 }
181
182 Ok(self.install_pipeline.clone().unwrap())
183 }
184
185 pub fn get_generation_pipeline(&mut self) -> Result<Arc<GenerationPipeline>> {
187 if self.generation_pipeline.is_none() {
188 let pipeline = GenerationPipeline::new(
189 self.get_config_manager()?,
190 self.get_proto_processor()?,
191 self.get_cache_manager()?,
192 );
193 self.generation_pipeline = Some(Arc::new(pipeline));
194 }
195
196 Ok(self.generation_pipeline.clone().unwrap())
197 }
198
199 pub fn validate(&self, required_components: &[ComponentType]) -> Result<()> {
201 for component_type in required_components {
202 match component_type {
203 ComponentType::ConfigManager => {
204 if self.config_manager.is_none() {
205 return Err(anyhow::anyhow!(
206 "ConfigManager is required but not registered"
207 ));
208 }
209 }
210 ComponentType::DependencyResolver => {
211 if self.dependency_resolver.is_none() {
212 return Err(anyhow::anyhow!(
213 "DependencyResolver is required but not registered"
214 ));
215 }
216 }
217 ComponentType::ServiceDiscovery => {
218 if self.service_discovery.is_none() {
219 return Err(anyhow::anyhow!(
220 "ServiceDiscovery is required but not registered"
221 ));
222 }
223 }
224 ComponentType::NetworkValidator => {
225 if self.network_validator.is_none() {
226 return Err(anyhow::anyhow!(
227 "NetworkValidator is required but not registered"
228 ));
229 }
230 }
231 ComponentType::FingerprintValidator => {
232 if self.fingerprint_validator.is_none() {
233 return Err(anyhow::anyhow!(
234 "FingerprintValidator is required but not registered"
235 ));
236 }
237 }
238 ComponentType::ProtoProcessor => {
239 if self.proto_processor.is_none() {
240 return Err(anyhow::anyhow!(
241 "ProtoProcessor is required but not registered"
242 ));
243 }
244 }
245 ComponentType::CacheManager => {
246 if self.cache_manager.is_none() {
247 return Err(anyhow::anyhow!(
248 "CacheManager is required but not registered"
249 ));
250 }
251 }
252 ComponentType::UserInterface => {
253 if self.user_interface.is_none() {
254 return Err(anyhow::anyhow!(
255 "UserInterface is required but not registered"
256 ));
257 }
258 }
259 }
260 }
261 Ok(())
262 }
263}
264
265impl Default for ServiceContainer {
266 fn default() -> Self {
267 Self::new()
268 }
269}
270
271pub struct ContainerBuilder {
273 container: ServiceContainer,
274 config_path: Option<std::path::PathBuf>,
275}
276
277impl ContainerBuilder {
278 pub fn new() -> Self {
280 Self {
281 container: ServiceContainer::new(),
282 config_path: None,
283 }
284 }
285
286 pub fn config_path<P: Into<std::path::PathBuf>>(mut self, path: P) -> Self {
288 self.config_path = Some(path.into());
289 self
290 }
291
292 pub fn build(self) -> Result<ServiceContainer> {
294 Ok(self.container)
298 }
299}
300
301impl Default for ContainerBuilder {
302 fn default() -> Self {
303 Self::new()
304 }
305}
306
307pub struct CommandContext {
309 pub container: Arc<std::sync::Mutex<ServiceContainer>>,
310 pub args: CommandArgs,
311 pub working_dir: std::path::PathBuf,
312}
313
314#[derive(Debug, Clone)]
316pub struct CommandArgs {
317 pub command: String,
318 pub subcommand: Option<String>,
319 pub flags: HashMap<String, String>,
320 pub positional: Vec<String>,
321}
322
323#[derive(Debug, Clone)]
325pub enum CommandResult {
326 Success(String),
327 Install(InstallResult),
328 Validation(ValidationReport),
329 Generation(GenerationResult),
330 Error(String),
331}
332
333#[async_trait::async_trait]
335pub trait Command: Send + Sync {
336 async fn execute(&self, context: &CommandContext) -> Result<CommandResult>;
338
339 fn required_components(&self) -> Vec<ComponentType>;
341
342 fn name(&self) -> &str;
344
345 fn description(&self) -> &str;
347}