Files
open-xiaoai/packages/server-python/src/python.rs
T

78 lines
2.1 KiB
Rust

use pyo3::prelude::*;
use std::collections::HashMap;
use std::ffi::CString;
use std::sync::{Arc, LazyLock, RwLock};
pub struct PythonManager {
functions: Arc<RwLock<HashMap<String, PyObject>>>,
}
static INSTANCE: LazyLock<PythonManager> = LazyLock::new(PythonManager::new);
impl PythonManager {
pub fn new() -> Self {
Self {
functions: Arc::new(RwLock::new(HashMap::new())),
}
}
pub fn instance() -> &'static Self {
&INSTANCE
}
fn register_fn(&self, key: &str, function: PyObject) -> PyResult<()> {
let mut functions = self.functions.write().unwrap();
functions.insert(key.to_string(), function);
Ok(())
}
fn unregister_fn(&self, key: &str) -> PyResult<()> {
let mut functions = self.functions.write().unwrap();
functions.remove(key);
Ok(())
}
pub fn call_fn(&self, key: &str, arg: Option<PyObject>) -> PyResult<PyObject> {
let functions = self.functions.read().unwrap();
if let Some(function) = functions.get(key) {
Python::with_gil(|py| match arg {
None => function.call0(py),
Some(arg) => function.call1(py, (arg,)),
})
} else {
Err(pyo3::exceptions::PyKeyError::new_err(format!(
"未找到函数: {}",
key
)))
}
}
pub fn log(&self, text: String) {
let _ = self.eval(&format!("print('{}')", text));
}
pub fn eval(&self, script: &str) -> PyResult<()> {
Python::with_gil(|py| {
let c_script = CString::new(script)?;
py.run(&c_script, None, None)?;
Ok(())
})
}
}
#[pyfunction]
fn register_fn(key: &str, function: PyObject) -> PyResult<()> {
PythonManager::instance().register_fn(key, function)
}
#[pyfunction]
fn unregister_fn(key: &str) -> PyResult<()> {
PythonManager::instance().unregister_fn(key)
}
pub fn init_module(m: &Bound<'_, PyModule>) -> PyResult<()> {
m.add_function(wrap_pyfunction!(register_fn, m)?)?;
m.add_function(wrap_pyfunction!(unregister_fn, m)?)?;
Ok(())
}