actr_cli/commands/initialize/
mod.rs1mod kotlin;
2mod python;
3mod rust;
4mod swift;
5pub mod traits;
6
7use crate::commands::SupportedLanguage;
8use crate::error::{ActrCliError, Result};
9use crate::template::{ProjectTemplateName, TemplateContext};
10use handlebars::Handlebars;
11use kotlin::KotlinInitializer;
12use python::PythonInitializer;
13use rust::RustInitializer;
14use std::path::Path;
15use swift::SwiftInitializer;
16
17pub use traits::{InitContext, ProjectInitializer};
18
19pub fn create_protoc_plugin_config(project_dir: &Path) -> Result<()> {
21 const DEFAULT_PLUGIN_MIN_VERSION: &str = "0.1.10";
22
23 let config_path = project_dir.join(".protoc-plugin.toml");
24 if config_path.exists() {
25 return Ok(());
26 }
27
28 if let Some(parent) = config_path.parent() {
29 std::fs::create_dir_all(parent)?;
30 }
31
32 let content = format!(
33 "version = 1\n\n[plugins]\nprotoc-gen-actrframework = \"{DEFAULT_PLUGIN_MIN_VERSION}\"\nprotoc-gen-actrframework-swift = \"{DEFAULT_PLUGIN_MIN_VERSION}\"\n"
34 );
35
36 std::fs::write(&config_path, content)?;
37 tracing::info!("📄 Created .protoc-plugin.toml");
38 Ok(())
39}
40
41pub fn create_local_proto(
43 project_dir: &Path,
44 project_name: &str,
45 proto_dir: &str,
46 template: ProjectTemplateName,
47) -> Result<()> {
48 let proto_path = project_dir.join(proto_dir);
49 std::fs::create_dir_all(&proto_path)?;
50
51 let fixtures_root = Path::new(env!("CARGO_MANIFEST_DIR")).join("fixtures");
53 let template_file_name = match template {
54 ProjectTemplateName::Echo => "local.echo.hbs",
55 ProjectTemplateName::DataStream => "local.data-stream.hbs",
56 };
57 let template_path = fixtures_root.join("protos").join(template_file_name);
58
59 let template_content = std::fs::read_to_string(&template_path).map_err(|e| {
60 ActrCliError::Io(std::io::Error::new(
61 std::io::ErrorKind::NotFound,
62 format!(
63 "Failed to read proto template {}: {}",
64 template_path.display(),
65 e
66 ),
67 ))
68 })?;
69
70 let template_context = TemplateContext::new(project_name, "", "");
72 let handlebars = Handlebars::new();
73
74 let local_proto_content = handlebars
76 .render_template(&template_content, &template_context)
77 .map_err(|e| {
78 ActrCliError::Io(std::io::Error::new(
79 std::io::ErrorKind::InvalidData,
80 format!("Failed to render proto template: {}", e),
81 ))
82 })?;
83
84 let local_proto_path = proto_path.join("local.proto");
85 std::fs::write(&local_proto_path, local_proto_content)?;
86
87 tracing::info!("📄 Created {}", local_proto_path.display());
88 Ok(())
89}
90
91pub struct InitializerFactory;
92
93impl InitializerFactory {
94 pub fn get_initializer(language: SupportedLanguage) -> Result<Box<dyn ProjectInitializer>> {
95 match language {
96 SupportedLanguage::Rust => Ok(Box::new(RustInitializer)),
97 SupportedLanguage::Python => Ok(Box::new(PythonInitializer)),
98 SupportedLanguage::Swift => Ok(Box::new(SwiftInitializer)),
99 SupportedLanguage::Kotlin => Ok(Box::new(KotlinInitializer)),
100 }
101 }
102}
103
104pub async fn execute_initialize(language: SupportedLanguage, context: &InitContext) -> Result<()> {
105 let initializer = InitializerFactory::get_initializer(language)?;
106 initializer.generate_project_structure(context).await?;
107 initializer.print_next_steps(context);
108 Ok(())
109}