use pyo3::prelude::*;
use pyo3::types::PyDict;
use std::path::PathBuf;
use crate::config::ProjectConfig;
mod config;
mod engine;
macro_rules! extract_config {
($dict:expr, $key:literal, required) => {{
if let Some(value) = $dict.get_item($key)? {
value.extract()?
} else {
return Err(PyErr::new::<pyo3::exceptions::PyValueError, _>(concat!(
$key,
" is required"
)));
}
}};
($dict:expr, $key:literal, $default:expr) => {{
if let Some(value) = $dict.get_item($key)? {
value.extract()?
} else {
$default
}
}};
}
#[pyfunction]
fn get_crate_version() -> String {
env!("CARGO_PKG_VERSION").to_string()
}
#[pyfunction]
fn run_engine(config_dict: &Bound<'_, PyDict>) -> PyResult<bool> {
let project_name: String = extract_config!(config_dict, "project_name", required);
let destination: String = extract_config!(config_dict, "destination", ".".to_string());
let destination_path = PathBuf::from(destination);
let author_name: String = extract_config!(config_dict, "author_name", "Test User".to_string());
let author_email: String =
extract_config!(config_dict, "author_email", "test@example.com".to_string());
let db_name: Option<String> = extract_config!(
config_dict,
"db_name",
Some(project_name.to_lowercase().replace('-', "_"))
);
let db_owner_admin: Option<String> = extract_config!(
config_dict,
"db_owner_admin",
Some(format!(
"{}_owner",
project_name.to_lowercase().replace('-', "_")
))
);
let db_owner_pword: Option<String> =
extract_config!(config_dict, "db_owner_pword", Some("password".to_string()));
let include_server: bool = extract_config!(config_dict, "include_server", true);
let include_frontend: bool = extract_config!(config_dict, "include_frontend", true);
let include_tauri_desktop: bool = extract_config!(config_dict, "include_tauri_desktop", true);
let app_identifier: String = extract_config!(
config_dict,
"app_identifier",
format!(
"com.example.{}",
project_name.to_lowercase().replace('-', "")
)
);
let deno_package_name: String = extract_config!(
config_dict,
"deno_package_name",
"@test/gwa-project".to_string()
);
let project_config = ProjectConfig {
project_name: project_name.clone(),
author_name,
author_email,
app_identifier,
db_name,
db_owner_admin,
db_owner_pword,
include_server,
include_frontend,
include_tauri_desktop,
deno_package_name,
};
match engine::run(&project_config, &destination_path) {
Ok(_) => Ok(true),
Err(e) => Err(PyErr::new::<pyo3::exceptions::PyRuntimeError, _>(format!(
"Failed to generate project with engine: {}",
e
))),
}
}
#[pymodule]
fn _core(m: &Bound<PyModule>) -> PyResult<()> {
m.add_function(wrap_pyfunction!(get_crate_version, m)?)?;
m.add_function(wrap_pyfunction!(run_engine, m)?)?;
Ok(())
}