pub use lazy_static::lazy_static;
pub mod macros;
use std::future::{Future, IntoFuture, Ready};
pub use zenoh_result::{bail, to_zerror, zerror};
pub mod zresult {
pub use zenoh_result::*;
}
pub use zresult::{Error, ZResult as Result};
pub trait Resolvable {
type To: Sized;
}
#[doc(hidden)]
pub trait IntoSendFuture: Resolvable {
type IntoFuture: Future<Output = Self::To> + Send;
}
impl<T> IntoSendFuture for T
where
T: Resolvable + IntoFuture<Output = Self::To>,
T::IntoFuture: Send,
{
type IntoFuture = T::IntoFuture;
}
pub trait Wait: Resolvable {
fn wait(self) -> Self::To;
}
#[must_use = "Resolvables do nothing unless you resolve them using `.await` or `zenoh::Wait::wait`"]
pub trait Resolve<Output>:
Resolvable<To = Output>
+ Wait
+ IntoSendFuture
+ IntoFuture<IntoFuture = <Self as IntoSendFuture>::IntoFuture, Output = Output>
+ Send
{
}
impl<T, Output> Resolve<Output> for T where
T: Resolvable<To = Output>
+ Wait
+ IntoSendFuture
+ IntoFuture<IntoFuture = <Self as IntoSendFuture>::IntoFuture, Output = Output>
+ Send
{
}
#[must_use = "Resolvables do nothing unless you resolve them using `.await` or `zenoh::Wait::wait`"]
pub struct ResolveClosure<C, To>(C)
where
To: Sized + Send,
C: FnOnce() -> To + Send;
impl<C, To> ResolveClosure<C, To>
where
To: Sized + Send,
C: FnOnce() -> To + Send,
{
pub fn new(c: C) -> Self {
Self(c)
}
}
impl<C, To> Resolvable for ResolveClosure<C, To>
where
To: Sized + Send,
C: FnOnce() -> To + Send,
{
type To = To;
}
impl<C, To> IntoFuture for ResolveClosure<C, To>
where
To: Sized + Send,
C: FnOnce() -> To + Send,
{
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<C, To> Wait for ResolveClosure<C, To>
where
To: Sized + Send,
C: FnOnce() -> To + Send,
{
fn wait(self) -> <Self as Resolvable>::To {
self.0()
}
}
#[must_use = "Resolvables do nothing unless you resolve them using `.await` or `zenoh::Wait::wait`"]
pub struct ResolveFuture<F, To>(F)
where
To: Sized + Send,
F: Future<Output = To> + Send;
impl<F, To> ResolveFuture<F, To>
where
To: Sized + Send,
F: Future<Output = To> + Send,
{
pub fn new(f: F) -> Self {
Self(f)
}
}
impl<F, To> Resolvable for ResolveFuture<F, To>
where
To: Sized + Send,
F: Future<Output = To> + Send,
{
type To = To;
}
impl<F, To> IntoFuture for ResolveFuture<F, To>
where
To: Sized + Send,
F: Future<Output = To> + Send,
{
type Output = To;
type IntoFuture = F;
fn into_future(self) -> Self::IntoFuture {
self.0
}
}
impl<F, To> Wait for ResolveFuture<F, To>
where
To: Sized + Send,
F: Future<Output = To> + Send,
{
fn wait(self) -> <Self as Resolvable>::To {
zenoh_runtime::ZRuntime::Application.block_in_place(self.0)
}
}
pub use zenoh_result::{likely, unlikely};
pub mod polyfill {
#[allow(clippy::wrong_self_convention)]
pub trait OptionExt<T>: Sized {
fn is_none_or(self, f: impl FnOnce(T) -> bool) -> bool;
}
impl<T> OptionExt<T> for Option<T> {
fn is_none_or(self, f: impl FnOnce(T) -> bool) -> bool {
match self {
None => true,
Some(x) => f(x),
}
}
}
}
#[macro_export]
macro_rules! debug_assert_implies {
($lhs:expr, $rhs:expr) => {
debug_assert!(!$lhs || $rhs)
};
}
#[macro_export]
macro_rules! bug {
($msg:literal) => {
if cfg!(debug_assertions) {
assert!(false, $msg);
} else {
tracing::error!(target: "zenoh::bug", $msg);
}
};
}