use crate::{apply_patch, apply_whole_files};
use pyo3::create_exception;
use pyo3::exceptions::PyException;
use pyo3::prelude::*;
use pyo3::types::{PyDict, PyModule};
use std::path::PathBuf;
create_exception!(_newt_agent, PyToolsError, PyException);
fn tools_err_to_py(e: anyhow::Error) -> PyErr {
PyToolsError::new_err(e.to_string())
}
#[pyfunction]
#[pyo3(name = "apply_patch")]
fn py_apply_patch(diff: &str, root: PathBuf) -> PyResult<()> {
apply_patch(&root, diff).map_err(tools_err_to_py)
}
#[pyfunction]
#[pyo3(name = "apply_whole_files")]
fn py_apply_whole_files(workspace: PathBuf, files: &Bound<'_, PyDict>) -> PyResult<Vec<String>> {
let mut pairs: Vec<(String, String)> = Vec::with_capacity(files.len());
for (k, v) in files.iter() {
let key: String = k.extract()?;
let val: String = v.extract()?;
pairs.push((key, val));
}
apply_whole_files(&workspace, pairs).map_err(tools_err_to_py)
}
pub fn register(py: Python<'_>, parent: &Bound<'_, PyModule>) -> PyResult<()> {
let m = PyModule::new(py, "tools")?;
m.add_function(wrap_pyfunction!(py_apply_patch, &m)?)?;
m.add_function(wrap_pyfunction!(py_apply_whole_files, &m)?)?;
m.add("ToolsError", py.get_type::<PyToolsError>())?;
parent.add_submodule(&m)?;
Ok(())
}