1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
//
// Copyright (c) 2023 ZettaScale Technology
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
//
// Contributors:
//   ZettaScale Zenoh Team, <zenoh@zettascale.tech>
//

//! ⚠️ WARNING ⚠️
//!
//! This crate is intended for Zenoh's internal use.
//!
//! [Click here for Zenoh's documentation](../zenoh/index.html)
pub use lazy_static::lazy_static;
pub mod macros;

use std::future::{Future, Ready};

// Re-exports after moving ZError/ZResult to zenoh-result
pub use zenoh_result::{bail, to_zerror, zerror};
pub mod zresult {
    pub use zenoh_result::*;
}
pub use zresult::Error;
pub use zresult::ZResult as Result;

pub trait Resolvable {
    type To: Sized + Send;
}

pub trait AsyncResolve: Resolvable {
    type Future: Future<Output = <Self as Resolvable>::To> + Send;

    fn res_async(self) -> Self::Future;

    fn res(self) -> Self::Future
    where
        Self: Sized,
    {
        self.res_async()
    }
}

pub trait SyncResolve: Resolvable {
    fn res_sync(self) -> <Self as Resolvable>::To;

    fn res(self) -> <Self as Resolvable>::To
    where
        Self: Sized,
    {
        self.res_sync()
    }
}

/// Zenoh's trait for resolving builder patterns.
///
/// Builder patterns in Zenoh can be resolved with [`AsyncResolve`] in async context and [`SyncResolve`] in sync context.
/// In both async and sync context calling `.res()` resolves the builder.
/// `.res()` maps to `.res_async()` in async context.
/// `.res()` maps to `.res_sync()` in sync context.
/// We advise to prefer the usage of [`AsyncResolve`] and to use [`SyncResolve`] with caution.
#[must_use = "Resolvables do nothing unless you resolve them using `.res()`."]
pub trait Resolve<Output>: Resolvable<To = Output> + SyncResolve + AsyncResolve + Send {}

impl<T, Output> Resolve<Output> for T where
    T: Resolvable<To = Output> + SyncResolve + AsyncResolve + Send
{
}

// Closure to wait
#[must_use = "Resolvables do nothing unless you resolve them using the `res` method from either `SyncResolve` or `AsyncResolve`"]
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> AsyncResolve for ResolveClosure<C, To>
where
    To: Sized + Send,
    C: FnOnce() -> To + Send,
{
    type Future = Ready<<Self as Resolvable>::To>;

    fn res_async(self) -> Self::Future {
        std::future::ready(self.res_sync())
    }
}

impl<C, To> SyncResolve for ResolveClosure<C, To>
where
    To: Sized + Send,
    C: FnOnce() -> To + Send,
{
    fn res_sync(self) -> <Self as Resolvable>::To {
        self.0()
    }
}

// Future to wait
#[must_use = "Resolvables do nothing unless you resolve them using the `res` method from either `SyncResolve` or `AsyncResolve`"]
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> AsyncResolve for ResolveFuture<F, To>
where
    To: Sized + Send,
    F: Future<Output = To> + Send,
{
    type Future = F;

    fn res_async(self) -> Self::Future {
        self.0
    }
}

impl<F, To> SyncResolve for ResolveFuture<F, To>
where
    To: Sized + Send,
    F: Future<Output = To> + Send,
{
    fn res_sync(self) -> <Self as Resolvable>::To {
        zenoh_runtime::ZRuntime::Application.block_in_place(self.0)
    }
}

pub use zenoh_result::{likely, unlikely};