use std::path::Path;
use std::error::Error;
use crate::stubgen::analyzer::*;
use std::fs::File;
use std::io::Write;
use std::fs::OpenOptions;
pub fn generate_stub(
python_src_data: &PythonSrcData,
output_dir: &Path,
module_name: &str,
) -> Result<(), Box<dyn Error>> {
let output_path = output_dir.join(format!("{}.pyi", module_name));
let mut file = OpenOptions::new()
.write(true)
.append(true)
.create(true)
.open(&output_path)
.map_err(|e| format!("File create failed: {}", e))?;
println!("Generating stub file: {}", output_path.display());
println!("Number of functions: {}", python_src_data.functions.len());
for function_data in &python_src_data.functions {
if function_data.name == module_name {
continue;
}
generate_function_stub(&mut file, function_data)?;
}
file.flush()?;
Ok(())
}
fn generate_function_stub(
file: &mut File,
function_data: &PythonFunctionData,
) -> Result<(), Box<dyn Error>> {
println!("Generating stub for function: {}", function_data.name);
if !function_data.doc.is_empty() {
writeln!(file, "# {}", function_data.doc)?;
}
let args_str = if function_data.args.is_empty() {
"".to_string()
} else {
function_data
.args
.iter()
.map(|(name, ty)| format!("{}: {}", name, ty))
.collect::<Vec<String>>()
.join(", ")
};
writeln!(
file,
"def {}({}) -> {}:",
function_data.name, args_str, function_data.return_type
)?;
writeln!(file, " ...")?;
writeln!(file)?;
file.flush()?;
Ok(())
}