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