use ocas_calc::solve::{
DiophantineSolution, SolveError, solve_diophantine as rs_diophantine,
solve_linear_integer as rs_linear_integer, solve_linear_rational as rs_linear_rational,
};
use pyo3::exceptions::PyValueError;
use pyo3::prelude::*;
fn map_solve_err(e: SolveError) -> PyErr {
PyValueError::new_err(e.to_string())
}
#[pyfunction]
#[pyo3(name = "solve_linear_rational")]
pub fn py_solve_linear_rational(a: Vec<Vec<i64>>, b: Vec<i64>) -> PyResult<Vec<(i64, i64)>> {
rs_linear_rational(&a, &b).map_err(map_solve_err)
}
#[pyfunction]
#[pyo3(name = "solve_linear_integer")]
pub fn py_solve_linear_integer(a: Vec<Vec<i64>>, b: Vec<i64>) -> PyResult<Vec<i64>> {
rs_linear_integer(&a, &b).map_err(map_solve_err)
}
#[pyclass(name = "DiophantineSolution")]
pub struct PyDiophantineSolution {
#[pyo3(get)]
pub particular: (i64, i64),
#[pyo3(get)]
pub general: (i64, i64),
}
impl From<DiophantineSolution> for PyDiophantineSolution {
fn from(s: DiophantineSolution) -> Self {
PyDiophantineSolution {
particular: s.particular,
general: s.general,
}
}
}
#[pyfunction]
#[pyo3(name = "solve_diophantine")]
pub fn py_solve_diophantine(a: i64, b: i64, c: i64) -> Option<PyDiophantineSolution> {
rs_diophantine(a, b, c).map(Into::into)
}