Skip to main content

zenoh_core/
lib.rs

1//
2// Copyright (c) 2023 ZettaScale Technology
3//
4// This program and the accompanying materials are made available under the
5// terms of the Eclipse Public License 2.0 which is available at
6// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
7// which is available at https://www.apache.org/licenses/LICENSE-2.0.
8//
9// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
10//
11// Contributors:
12//   ZettaScale Zenoh Team, <zenoh@zettascale.tech>
13//
14
15//! ⚠️ WARNING ⚠️
16//!
17//! This crate is intended for Zenoh's internal use.
18//!
19//! [Click here for Zenoh's documentation](https://docs.rs/zenoh/latest/zenoh)
20pub use lazy_static::lazy_static;
21pub mod macros;
22
23use std::future::{Future, IntoFuture, Ready};
24
25// Re-exports after moving ZError/ZResult to zenoh-result
26pub use zenoh_result::{bail, to_zerror, zerror};
27pub mod zresult {
28    pub use zenoh_result::*;
29}
30pub use zresult::{Error, ZResult as Result};
31
32/// A resolvable execution, either sync or async
33pub trait Resolvable {
34    type To: Sized;
35}
36
37/// Trick used to mark `<Resolve as IntoFuture>::IntoFuture` bound as Send
38#[doc(hidden)]
39pub trait IntoSendFuture: Resolvable {
40    type IntoFuture: Future<Output = Self::To> + Send;
41}
42
43impl<T> IntoSendFuture for T
44where
45    T: Resolvable + IntoFuture<Output = Self::To>,
46    T::IntoFuture: Send,
47{
48    type IntoFuture = T::IntoFuture;
49}
50
51/// Synchronous execution of a resolvable
52pub trait Wait: Resolvable {
53    /// Synchronously execute and wait
54    fn wait(self) -> Self::To;
55}
56
57/// Zenoh's trait for resolving builder patterns.
58///
59/// Builder patterns in Zenoh can be resolved by awaiting them, in async context,
60/// and [`Wait::wait`] in sync context.
61/// We advise to prefer the usage of asynchronous execution, and to use synchronous one with caution
62#[must_use = "Resolvables do nothing unless you resolve them using `.await` or `zenoh::Wait::wait`"]
63pub trait Resolve<Output>:
64    Resolvable<To = Output>
65    + Wait
66    + IntoSendFuture
67    + IntoFuture<IntoFuture = <Self as IntoSendFuture>::IntoFuture, Output = Output>
68    + Send
69{
70}
71
72impl<T, Output> Resolve<Output> for T where
73    T: Resolvable<To = Output>
74        + Wait
75        + IntoSendFuture
76        + IntoFuture<IntoFuture = <Self as IntoSendFuture>::IntoFuture, Output = Output>
77        + Send
78{
79}
80
81// Closure to wait
82#[must_use = "Resolvables do nothing unless you resolve them using `.await` or `zenoh::Wait::wait`"]
83pub struct ResolveClosure<C, To>(C)
84where
85    To: Sized + Send,
86    C: FnOnce() -> To + Send;
87
88impl<C, To> ResolveClosure<C, To>
89where
90    To: Sized + Send,
91    C: FnOnce() -> To + Send,
92{
93    pub fn new(c: C) -> Self {
94        Self(c)
95    }
96}
97
98impl<C, To> Resolvable for ResolveClosure<C, To>
99where
100    To: Sized + Send,
101    C: FnOnce() -> To + Send,
102{
103    type To = To;
104}
105
106impl<C, To> IntoFuture for ResolveClosure<C, To>
107where
108    To: Sized + Send,
109    C: FnOnce() -> To + Send,
110{
111    type Output = <Self as Resolvable>::To;
112    type IntoFuture = Ready<<Self as Resolvable>::To>;
113
114    fn into_future(self) -> Self::IntoFuture {
115        std::future::ready(self.wait())
116    }
117}
118
119impl<C, To> Wait for ResolveClosure<C, To>
120where
121    To: Sized + Send,
122    C: FnOnce() -> To + Send,
123{
124    fn wait(self) -> <Self as Resolvable>::To {
125        self.0()
126    }
127}
128
129// Future to wait
130#[must_use = "Resolvables do nothing unless you resolve them using `.await` or `zenoh::Wait::wait`"]
131pub struct ResolveFuture<F, To>(F)
132where
133    To: Sized + Send,
134    F: Future<Output = To> + Send;
135
136impl<F, To> ResolveFuture<F, To>
137where
138    To: Sized + Send,
139    F: Future<Output = To> + Send,
140{
141    pub fn new(f: F) -> Self {
142        Self(f)
143    }
144}
145
146impl<F, To> Resolvable for ResolveFuture<F, To>
147where
148    To: Sized + Send,
149    F: Future<Output = To> + Send,
150{
151    type To = To;
152}
153
154impl<F, To> IntoFuture for ResolveFuture<F, To>
155where
156    To: Sized + Send,
157    F: Future<Output = To> + Send,
158{
159    type Output = To;
160    type IntoFuture = F;
161
162    fn into_future(self) -> Self::IntoFuture {
163        self.0
164    }
165}
166
167impl<F, To> Wait for ResolveFuture<F, To>
168where
169    To: Sized + Send,
170    F: Future<Output = To> + Send,
171{
172    fn wait(self) -> <Self as Resolvable>::To {
173        zenoh_runtime::ZRuntime::Application.block_in_place(self.0)
174    }
175}
176
177pub use zenoh_result::{likely, unlikely};
178
179/// Re-definitions of inaccessible [`std`] items for MSRV compatibility.
180///
181/// These definitions are likely to cause `incompatible_msrv` warnings from clippy,
182/// see <https://github.com/rust-lang/rust-clippy/issues/12280>.
183pub mod polyfill {
184    // TODO: use rustversion?
185
186    // NOTE: `Option::is_none_or` was stabilized in 1.82.0 > 1.75.0
187    #[allow(clippy::wrong_self_convention)]
188    pub trait OptionExt<T>: Sized {
189        fn is_none_or(self, f: impl FnOnce(T) -> bool) -> bool;
190    }
191
192    impl<T> OptionExt<T> for Option<T> {
193        fn is_none_or(self, f: impl FnOnce(T) -> bool) -> bool {
194            match self {
195                None => true,
196                Some(x) => f(x),
197            }
198        }
199    }
200}
201
202/// Asserts that the LHS expression implies the RHS expression.
203///
204/// Note that in logic, `p ⟹ q` is equivalent to `¬p ∨ q` (i.e. `!p || q`).
205#[macro_export]
206macro_rules! debug_assert_implies {
207    ($lhs:expr, $rhs:expr) => {
208        debug_assert!(!$lhs || $rhs)
209    };
210}
211
212/// Panics with the given message in debug mode or logs an error otherwise.
213#[macro_export]
214macro_rules! bug {
215    ($msg:literal) => {
216        if cfg!(debug_assertions) {
217            assert!(false, $msg);
218        } else {
219            tracing::error!(target: "zenoh::bug", $msg);
220        }
221    };
222}