use rayon::prelude::*;
use std::env;
use std::fs::{self, File};
use std::io::Write;
use std::path::Path;
use syn::parse_file;
use tauri_helper_core::{find_workspace_dir, get_workspace, get_workspace_members};
use walkdir::WalkDir;
pub use tauri_helper_core::types::TauriHelperOptions;
pub use tauri_helper_macros::*;
#[allow(clippy::needless_doctest_main)]
pub fn generate_command_file(options: TauriHelperOptions) {
let workspace_root = find_workspace_dir(Path::new(&env::var("CARGO_MANIFEST_DIR").unwrap()));
let commands_dir = workspace_root.join("target").join("tauri_commands_list");
fs::create_dir_all(&commands_dir).unwrap();
let workspace_members = options
.members
.clone()
.unwrap_or_else(|| get_workspace_members(&workspace_root));
for member in &workspace_members {
println!("cargo:rerun-if-changed={}", member);
}
workspace_members.par_iter().for_each(|member| {
let manifest_dir = workspace_root.join(member);
let crate_name = manifest_dir
.file_name()
.and_then(|n| n.to_str())
.unwrap_or_default()
.to_string();
let src_dir = manifest_dir.join("src");
let mut functions = Vec::new();
let rs_files: Vec<_> = WalkDir::new(&src_dir)
.into_iter()
.filter_map(|e| e.ok())
.filter(|e| e.path().extension().and_then(|x| x.to_str()) == Some("rs"))
.collect();
let file_fns: Vec<String> = rs_files
.par_iter()
.filter_map(|entry| {
let path = entry.path();
let content = fs::read_to_string(path).ok()?;
if !content.contains("tauri::command") && !content.contains("auto_collect_command")
{
return None;
}
let ast = parse_file(&content).ok()?;
let mut found = Vec::new();
for item in ast.items {
if let syn::Item::Fn(func) = item {
if !options.collect_all {
if func
.attrs
.iter()
.any(|a| a.path().is_ident("auto_collect_command"))
{
found.push(func.sig.ident.to_string());
}
} else if func.attrs.iter().any(|a| {
let p = a.path();
p.is_ident("command")
|| (p.segments.len() == 2
&& p.segments[0].ident == "tauri"
&& p.segments[1].ident == "command")
}) {
found.push(func.sig.ident.to_string());
}
}
}
Some(found)
})
.flatten()
.collect();
functions.extend(file_fns);
if !functions.is_empty() {
let package_name = get_workspace().package.name.replace('-', "_");
let command_file = commands_dir.join(format!("{}.txt", crate_name));
let mut file = File::create(&command_file).unwrap();
for func in functions {
let full_name = if crate_name.replace('-', "_") == "src_tauri" {
format!("{}::{}", package_name, func)
} else {
format!("{}::{}", crate_name.replace('-', "_"), func)
};
writeln!(file, "{}", full_name).unwrap();
}
}
});
}