mod traits;
mod cli;
mod template;
use serde_json::Value;
pub use traits::ProjectHandler;
pub use cli::CliProjectHandler;
pub use template::TemplateProjectHandler;
pub fn get_handlers() -> Vec<Box<dyn ProjectHandler>> {
let mut handlers: Vec<Box<dyn ProjectHandler>> = Vec::new();
handlers.push(Box::new(CliProjectHandler::new(
"Embassy",
"Embedded systems with the Embassy framework",
vec!["embedded-embassy".to_string()],
"cargo embassy",
|project_name, _target_dir, variables| {
let mut args = vec!["init".to_string()];
if let Some(target) = variables.get("mcu_target").and_then(|t| t.as_str()) {
let chip = match target {
"esp32" => "esp32c3",
_ => target
};
args.push("--chip".to_string());
args.push(chip.to_string());
}
args.push(project_name.to_string());
args
},
|project_name, _variables| {
vec![
format!("🚀 Navigate to your project: cd {}", project_name),
"📝 Review the generated code".to_string(),
"🔧 Build the project: cargo build --release".to_string(),
"▶️ Flash the project: cargo run --release".to_string(),
"📚 Read the Embassy documentation: https://embassy.dev".to_string()
]
},
Some("cargo install cargo-embassy".to_string()),
Some("cargo embassy --version".to_string()),
)));
handlers.push(Box::new(CliProjectHandler::new(
"Dioxus",
"Cross-platform UI toolkit for Rust",
vec!["client-dioxus".to_string(), "dioxus".to_string()],
"dioxus create",
|project_name, _target_dir, variables| {
let mut args = vec![project_name.to_string()];
if let Some(platform) = variables.get("platform").and_then(|p| p.as_str()) {
args.push("--platform".to_string());
args.push(platform.to_string());
} else {
args.push("--platform".to_string());
args.push("web".to_string());
}
args
},
|project_name, variables| {
let platform = variables.get("platform").and_then(|p| p.as_str()).unwrap_or("web");
match platform {
"web" => vec![
format!("🚀 Navigate to your project: cd {}", project_name),
"📝 Review the generated code".to_string(),
"🔧 Build the project: dx serve".to_string(),
"🌐 View your app at http://localhost:8080".to_string(),
],
"desktop" => vec![
format!("🚀 Navigate to your project: cd {}", project_name),
"📝 Review the generated code".to_string(),
"🔧 Build the project: dx build --release".to_string(),
"▶️ Run the project: dx serve".to_string(),
],
_ => vec![
format!("🚀 Navigate to your project: cd {}", project_name),
"📝 Review the generated code".to_string(),
"🔧 Build the project: dx build".to_string(),
"▶️ Run the project: dx serve".to_string(),
]
}
},
Some("cargo install dioxus-cli".to_string()),
Some("dioxus --version".to_string()),
)));
handlers.push(Box::new(CliProjectHandler::new(
"Tauri",
"Build desktop applications with web technologies",
vec!["client-tauri".to_string(), "tauri".to_string()],
"cargo tauri",
|project_name, _target_dir, _variables| {
vec!["init".to_string(), "--app".to_string(), project_name.to_string()]
},
|project_name, _variables| {
vec![
format!("🚀 Navigate to your project: cd {}", project_name),
"📝 Review the generated code".to_string(),
"🔧 Build the project: cargo tauri dev".to_string(),
"📦 Package for distribution: cargo tauri build".to_string(),
]
},
Some("cargo install tauri-cli".to_string()),
Some("cargo tauri --version".to_string()),
)));
handlers.push(Box::new(TemplateProjectHandler::new(
"Full Stack",
"Complete application with client, server, and ferrisup_common libraries",
vec!["full-stack".to_string()]
)));
handlers.push(Box::new(TemplateProjectHandler::new(
"Server",
"Web server with API endpoints",
vec!["server".to_string(), "axum".to_string(), "actix".to_string(), "poem".to_string()]
)));
handlers.push(Box::new(TemplateProjectHandler::new(
"Data Science",
"Data science and machine learning projects",
vec!["data-science".to_string(), "burn".to_string(), "linfa".to_string()]
)));
handlers.push(Box::new(TemplateProjectHandler::new(
"Edge",
"WebAssembly-based applications for edge computing",
vec!["edge".to_string(), "edge-app".to_string()]
)));
handlers.push(Box::new(TemplateProjectHandler::new(
"Embedded",
"Embedded systems firmware for microcontrollers",
vec!["embedded".to_string()]
)));
handlers.push(Box::new(TemplateProjectHandler::new(
"Serverless",
"Serverless functions for cloud deployment",
vec!["serverless".to_string()]
)));
handlers.push(Box::new(TemplateProjectHandler::new(
"Generic",
"Generic template handler for all other templates",
vec!["minimal".to_string(), "library".to_string(), "iot-device".to_string(), "ml-pipeline".to_string()]
)));
handlers
}
pub fn find_handler(template_name: &str, variables: &Value) -> Option<Box<dyn ProjectHandler>> {
for handler in get_handlers() {
if handler.can_handle(template_name, variables) {
return Some(handler);
}
}
None
}