use std::sync::Arc;
use futures::future::BoxFuture;
#[cfg(doc)]
use perspective_client::{Client, Table};
use perspective_server::ServerResult;
use pollster::FutureExt;
use pyo3::IntoPyObjectExt;
use pyo3::exceptions::PyValueError;
use pyo3::prelude::*;
use pyo3::types::PyAny;
use super::session_sync::{PyConnectionSync, PySession};
use crate::client::client_async::AsyncClient;
#[pyclass(subclass, module = "perspective")]
#[derive(Clone)]
pub struct Server {
pub server: perspective_server::Server,
}
#[pymethods]
impl Server {
#[new]
#[pyo3(signature = (on_poll_request=None))]
pub fn new(on_poll_request: Option<Py<PyAny>>) -> Self {
Self {
server: perspective_server::Server::new(on_poll_request.map(|f| {
let f = Arc::new(f);
Arc::new(move |server: &perspective_server::Server| {
let f = f.clone();
let server = server.clone();
Box::pin(async move {
Python::with_gil(|py| {
f.call1(py, (Server { server }.into_py_any(py).unwrap(),))
})?;
Ok(())
}) as BoxFuture<'static, ServerResult<()>>
})
as Arc<
dyn Fn(&perspective_server::Server) -> BoxFuture<'static, ServerResult<()>>
+ Send
+ Sync,
>
})),
}
}
pub fn new_local_client(&self) -> PyResult<crate::client::client_sync::Client> {
let client = crate::client::client_sync::Client(AsyncClient::new_from_client(
self.server
.new_local_client()
.take()
.map_err(PyValueError::new_err)?,
));
Ok(client)
}
pub fn new_session(&self, _py: Python, response_cb: Py<PyAny>) -> PySession {
let session = self
.server
.new_session(PyConnectionSync(response_cb.into()))
.block_on();
let session = Arc::new(std::sync::RwLock::new(Some(session)));
PySession { session }
}
pub fn poll(&self, py: Python<'_>) -> PyResult<()> {
py.allow_threads(|| {
self.server
.poll()
.block_on()
.map_err(|e| PyValueError::new_err(format!("{e}")))
})
}
}