use crate::{err::Error, rctx::RCtxState, server::InnerMsgType};
#[repr(transparent)]
pub struct Client<P, S, R, E>(
pub(crate) sigq::Pusher<InnerMsgType<P, S, R, E>>
);
impl<P, S, R, E> Client<P, S, R, E>
where
P: 'static + Send,
R: 'static + Send,
E: 'static + Send
{
pub fn post(&self, msg: P) -> Result<(), Error<E>> {
self
.0
.push(InnerMsgType::Post(msg))
.map_err(|_| Error::ServerDisappeared)?;
Ok(())
}
pub fn req(&self, out: S) -> Result<R, Error<E>> {
let (sctx, wctx) = swctx::mkpair();
self
.0
.push(InnerMsgType::Request(out, sctx))
.map_err(|_| Error::ServerDisappeared)?;
Ok(wctx.wait()?)
}
pub fn req_async(&self, out: S) -> Result<WaitReply<R, E>, Error<E>> {
let (sctx, wctx) = swctx::mkpair();
self
.0
.push(InnerMsgType::Request(out, sctx))
.map_err(|_| Error::ServerDisappeared)?;
Ok(WaitReply(wctx))
}
#[allow(clippy::missing_errors_doc)]
pub async fn areq(&self, out: S) -> Result<R, Error<E>>
where
S: Send
{
let (sctx, wctx) = swctx::mkpair();
self
.0
.push(InnerMsgType::Request(out, sctx))
.map_err(|_| Error::ServerDisappeared)?;
Ok(wctx.wait_async().await?)
}
#[must_use]
pub fn weak(&self) -> Weak<P, S, R, E> {
Weak(self.0.weak())
}
#[must_use]
pub fn postclient(&self) -> Post<P, S, R, E> {
Post(self.clone())
}
}
impl<P, S, R, E> Clone for Client<P, S, R, E> {
fn clone(&self) -> Self {
Self(self.0.clone())
}
}
pub struct WaitReply<R, E>(swctx::WaitCtx<R, RCtxState, E>);
impl<R, E> WaitReply<R, E> {
pub fn wait(self) -> Result<R, Error<E>> {
Ok(self.0.wait()?)
}
#[allow(clippy::missing_errors_doc)]
pub async fn wait_async(self) -> Result<R, Error<E>>
where
R: Send,
E: Send
{
Ok(self.0.wait_async().await?)
}
}
#[repr(transparent)]
pub struct Weak<P, S, R, E>(
pub(crate) sigq::WeakPusher<InnerMsgType<P, S, R, E>>
);
impl<P, S, R, E> Clone for Weak<P, S, R, E> {
fn clone(&self) -> Self {
Self(self.0.clone())
}
}
impl<P, S, R, E> Weak<P, S, R, E> {
#[must_use]
pub fn upgrade(&self) -> Option<Client<P, S, R, E>> {
self.0.upgrade().map(|x| Client(x))
}
}
#[derive(Clone)]
#[repr(transparent)]
pub struct Post<P, S, R, E>(Client<P, S, R, E>);
impl<P, S, R, E> Post<P, S, R, E>
where
P: 'static + Send,
S: 'static + Send,
R: 'static + Send,
E: 'static + Send
{
pub fn post(&self, msg: P) -> Result<(), Error<E>> {
self.0.post(msg)
}
}