PTS/cepitodb-master/src/python.rs

77 lines
1.7 KiB
Rust
Raw Normal View History

2024-04-09 12:30:03 +00:00
use pyo3::{
prelude::*,
types::{PyModule, PyTuple},
};
use anyhow::Result;
pub enum PythonScript<'a> {
File(&'a [u8]),
Path(&'a str),
}
impl<'a> From<&'a [u8]> for PythonScript<'a> {
fn from(content: &'a [u8]) -> Self {
PythonScript::File(content)
}
}
impl<'a> From<&'a str> for PythonScript<'a> {
fn from(path: &'a str) -> Self {
PythonScript::Path(path)
}
}
pub struct PythonObject {
script: String,
}
impl PythonObject {
pub fn new<'a>(script: impl Into<PythonScript<'a>>) -> Result<Self> {
Ok(Self {
script: match script.into() {
PythonScript::File(file) => std::str::from_utf8(file)?.to_string(),
PythonScript::Path(path) => std::fs::read_to_string(path)?,
},
})
}
pub fn execute_script<D, F, O, I>(&self, function_name: &str, i: I, f: F) -> Result<O>
where
I: ToPyObject,
D: for<'a> FromPyObject<'a>,
F: FnOnce(D) -> Result<O>,
{
Ok(Python::with_gil(|py| -> Result<O> {
let module = PyModule::from_code(py, &self.script, "dummy", "dummy")?;
let args = PyTuple::new(py, [i]);
Ok(f(module.getattr(function_name)?.call1(args)?.extract()?)?)
})?)
}
}
#[cfg(test)]
mod test {
use anyhow::Result;
use std::collections::HashMap;
use super::PythonObject;
#[test]
fn verify_python() -> Result<()> {
let cepi_reader = PythonObject::new("resources/cepi_read_function.py")?;
let cepi_data = cepi_reader.execute_script(
"read",
"resources/dummy.xlsx",
|r: HashMap<String, HashMap<String, String>>| Ok(r),
)?;
println!("{:#?}", cepi_data);
Ok(())
}
}