use pyo3::prelude::*;
use crate::python::service::{PyServiceHandler, PythonServiceBridge};
use crate::python::types::PyTlsConfig;
use crate::server::Server;
#[pyclass(name = "RpcServer")]
pub struct PyRpcServer {
bind_addr: String,
tls_config: PyTlsConfig,
services: Vec<PythonServiceBridge>,
}
#[pymethods]
impl PyRpcServer {
#[new]
fn new(bind_addr: String, tls: PyTlsConfig) -> Self {
Self {
bind_addr,
tls_config: tls,
services: Vec::new(),
}
}
fn add_service(&mut self, handler: &PyServiceHandler) {
self.services
.push(PythonServiceBridge::from_handler(handler));
}
fn start<'py>(&mut self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> {
let bind_addr = self.bind_addr.clone();
let tls_config = self.tls_config.inner.clone();
let services = std::mem::take(&mut self.services);
pyo3_async_runtimes::tokio::future_into_py(py, async move {
let mut builder = Server::builder();
builder = builder
.bind_str(&bind_addr)
.map_err(|e| pyo3::exceptions::PyRuntimeError::new_err(e.to_string()))?;
builder = builder.tls(tls_config);
for service in services {
builder = builder.add_service(service);
}
let server = builder
.build()
.map_err(|e| pyo3::exceptions::PyRuntimeError::new_err(e.to_string()))?;
server
.serve()
.await
.map_err(|e| pyo3::exceptions::PyRuntimeError::new_err(e.to_string()))?;
Ok(())
})
}
}