use std::{
convert::TryInto,
future::{IntoFuture, Ready},
};
use tracing::error;
use zenoh_core::{Resolvable, Resolve, Result as ZResult, Wait};
use crate::api::{
builders::liveliness::{
LivelinessGetBuilder, LivelinessSubscriberBuilder, LivelinessTokenBuilder,
},
handlers::DefaultHandler,
key_expr::KeyExpr,
session::{Session, UndeclarableSealed, WeakSession},
Id,
};
pub struct Liveliness<'a> {
pub(crate) session: &'a Session,
}
impl<'a> Liveliness<'a> {
pub fn declare_token<'b, TryIntoKeyExpr>(
&self,
key_expr: TryIntoKeyExpr,
) -> LivelinessTokenBuilder<'a, 'b>
where
TryIntoKeyExpr: TryInto<KeyExpr<'b>>,
<TryIntoKeyExpr as TryInto<KeyExpr<'b>>>::Error: Into<zenoh_core::Error>,
{
LivelinessTokenBuilder {
session: self.session,
key_expr: TryIntoKeyExpr::try_into(key_expr).map_err(Into::into),
}
}
pub fn declare_subscriber<'b, TryIntoKeyExpr>(
&self,
key_expr: TryIntoKeyExpr,
) -> LivelinessSubscriberBuilder<'a, 'b, DefaultHandler>
where
TryIntoKeyExpr: TryInto<KeyExpr<'b>>,
<TryIntoKeyExpr as TryInto<KeyExpr<'b>>>::Error: Into<zenoh_result::Error>,
{
LivelinessSubscriberBuilder {
session: self.session,
key_expr: TryIntoKeyExpr::try_into(key_expr).map_err(Into::into),
handler: DefaultHandler::default(),
history: false,
}
}
pub fn get<'b, TryIntoKeyExpr>(
&self,
key_expr: TryIntoKeyExpr,
) -> LivelinessGetBuilder<'a, 'b, DefaultHandler>
where
TryIntoKeyExpr: TryInto<KeyExpr<'b>>,
<TryIntoKeyExpr as TryInto<KeyExpr<'b>>>::Error: Into<zenoh_result::Error>,
{
let key_expr = key_expr.try_into().map_err(Into::into);
LivelinessGetBuilder {
session: self.session,
key_expr,
timeout: self.session.queries_default_timeout(),
handler: DefaultHandler::default(),
#[cfg(feature = "unstable")]
cancellation_token: None,
}
}
}
#[must_use = "Liveliness tokens will be immediately dropped and undeclared if not bound to a variable"]
#[derive(Debug)]
pub struct LivelinessToken {
pub(crate) session: WeakSession,
pub(crate) id: Id,
pub(crate) undeclare_on_drop: bool,
}
#[must_use = "Resolvables do nothing unless you resolve them using `.await` or `zenoh::Wait::wait`"]
pub struct LivelinessTokenUndeclaration(LivelinessToken);
impl Resolvable for LivelinessTokenUndeclaration {
type To = ZResult<()>;
}
impl Wait for LivelinessTokenUndeclaration {
fn wait(mut self) -> <Self as Resolvable>::To {
self.0.undeclare_impl()
}
}
impl IntoFuture for LivelinessTokenUndeclaration {
type Output = <Self as Resolvable>::To;
type IntoFuture = Ready<<Self as Resolvable>::To>;
fn into_future(self) -> Self::IntoFuture {
std::future::ready(self.wait())
}
}
impl LivelinessToken {
#[inline]
pub fn undeclare(self) -> impl Resolve<ZResult<()>> {
UndeclarableSealed::undeclare_inner(self, ())
}
fn undeclare_impl(&mut self) -> ZResult<()> {
self.undeclare_on_drop = false;
self.session.undeclare_liveliness(self.id)
}
}
impl UndeclarableSealed<()> for LivelinessToken {
type Undeclaration = LivelinessTokenUndeclaration;
fn undeclare_inner(self, _: ()) -> Self::Undeclaration {
LivelinessTokenUndeclaration(self)
}
}
impl Drop for LivelinessToken {
fn drop(&mut self) {
if self.undeclare_on_drop {
if let Err(error) = self.undeclare_impl() {
error!(error);
}
}
}
}