tuwunel_core/utils/mod.rs
1//! Reusable helpers and extension traits for core services.
2//!
3//! The module groups compile-time assertions, closure-producing macros, and
4//! common utilities shared across workspace crates. Frequently used helpers are
5//! re-exported through a single import path.
6
7pub mod arrayvec;
8pub mod bool;
9pub mod bytes;
10pub mod content_disposition;
11pub mod debug;
12pub mod defer;
13pub mod future;
14pub mod hash;
15pub mod html;
16pub mod json;
17pub mod math;
18pub mod mutex_map;
19pub mod option;
20pub mod rand;
21pub mod result;
22pub mod secret;
23pub mod set;
24pub mod stream;
25pub mod string;
26pub mod sys;
27#[cfg(test)]
28mod tests;
29pub mod time;
30pub mod two_phase_counter;
31pub mod unhandled;
32pub mod url;
33
34pub use ::ctor::ctor;
35pub use ::dtor::dtor;
36pub use ::tuwunel_macros::{async_noinline, implement};
37
38pub use self::{
39 arrayvec::ArrayVecExt,
40 bool::BoolExt,
41 bytes::{increment, u64_from_bytes, u64_from_u8},
42 debug::slice_truncated as debug_slice_truncated,
43 future::{BoolExt as FutureBoolExt, OptionStream, TryExtExt as TryFutureExtExt},
44 hash::sha256::delimited as calculate_hash,
45 json::{deserialize_from_str, serialized_len, to_canonical_object},
46 mutex_map::{Guard as MutexMapGuard, MutexMap},
47 option::OptionExt,
48 rand::{shuffle, string as random_string, string_from as random_string_from},
49 secret::{Secret, is_set as is_secret_set, resolve as resolve_secret},
50 stream::{IterStream, ReadyExt, Tools as StreamTools, TryReadyExt},
51 string::{str_from_bytes, string_from_bytes},
52 sys::compute::available_parallelism,
53 time::{
54 exponential_backoff::{
55 continue_exponential_backoff, continue_exponential_backoff_secs,
56 exponential_backoff_streak_cap,
57 },
58 now_millis as millis_since_unix_epoch, timepoint_ago, timepoint_from_now,
59 timepoint_has_passed,
60 },
61};
62
63/// Asserts at compile time that `T` implements `Send`.
64///
65/// The generic bound supplies the assertion, and the function performs no
66/// runtime work.
67pub const fn assert_send<T: Send>() {}
68
69/// Asserts at compile time that `T` implements `Sync`.
70///
71/// The generic bound supplies the assertion, and the function performs no
72/// runtime work.
73pub const fn assert_sync<T: Sync>() {}
74
75/// Accepts any type, including an unsized type, without performing work.
76///
77/// The `?Sized` bound removes the implicit `Sized` requirement. The const
78/// signature permits use from const contexts.
79pub const fn assert_dst<T: ?Sized>() {}
80
81/// Asserts at compile time that `T` implements `Sized`.
82///
83/// The generic bound supplies the assertion, and the function performs no
84/// runtime work.
85pub const fn assert_sized<T: Sized>() {}
86
87/// Asserts at compile time that `T` implements `Unpin`.
88///
89/// The generic bound supplies the assertion, and the function performs no
90/// runtime work.
91pub const fn assert_unpin<T: Unpin>() {}
92
93/// Asserts at compile time that `T` implements `UnwindSafe`.
94///
95/// The generic bound supplies the assertion, and the function performs no
96/// runtime work.
97pub const fn assert_unwind_safe<T: std::panic::UnwindSafe>() {}
98
99/// Asserts at compile time that `T` implements `RefUnwindSafe`.
100///
101/// The generic bound supplies the assertion, and the function performs no
102/// runtime work.
103pub const fn assert_ref_unwind_safe<T: std::panic::RefUnwindSafe>() {}
104
105/// Extracts the payload from any listed tuple variant into an `Option`.
106///
107/// The expression is matched once, and a listed variant returns
108/// `Some(payload)`. Every other variant returns `None`.
109#[macro_export]
110macro_rules! extract_variant {
111 ( $e:expr_2021, $( $variant:path )|* ) => {
112 match $e {
113 $( $variant(value) => Some(value), )*
114 _ => None,
115 }
116 };
117}
118
119/// Extracts a pattern-bound value into an `Option`.
120///
121/// The expression is matched once against the supplied pattern. A match returns
122/// the named binding in `Some`, while every other value returns `None`.
123#[macro_export]
124macro_rules! extract {
125 ($e:expr_2021, $out:ident in $variant:pat) => {
126 match $e {
127 | $variant => Some($out),
128 | _ => None,
129 }
130 };
131}
132
133/// Creates a closure that reports whether its input is nonempty.
134///
135/// The generated closure delegates to `is_empty` and negates the result.
136#[macro_export]
137macro_rules! is_not_empty {
138 () => {
139 |x| !x.is_empty()
140 };
141}
142
143/// Creates a closure that applies one callable to every field of a tuple.
144///
145/// Tuple arities from one through five are supported. The callable tokens are
146/// expanded once for each field and therefore may be evaluated more than once.
147#[macro_export]
148macro_rules! apply {
149 (1, $($idx:tt)+) => {
150 |t| (($($idx)+)(t.0),)
151 };
152
153 (2, $($idx:tt)+) => {
154 |t| (($($idx)+)(t.0), ($($idx)+)(t.1),)
155 };
156
157 (3, $($idx:tt)+) => {
158 |t| (($($idx)+)(t.0), ($($idx)+)(t.1), ($($idx)+)(t.2),)
159 };
160
161 (4, $($idx:tt)+) => {
162 |t| (($($idx)+)(t.0), ($($idx)+)(t.1), ($($idx)+)(t.2), ($($idx)+)(t.3),)
163 };
164
165 (5, $($idx:tt)+) => {
166 |t| (($($idx)+)(t.0), ($($idx)+)(t.1), ($($idx)+)(t.2), ($($idx)+)(t.3), ($($idx)+)(t.4),)
167 };
168}
169
170/// Expands a type or expression into a two-element tuple with identical
171/// entries.
172///
173/// The type form produces `(T, T)`. The expression form evaluates the supplied
174/// expression separately for each tuple element.
175#[macro_export]
176macro_rules! pair_of {
177 ($decl:ty) => {
178 ($decl, $decl)
179 };
180
181 ($init:expr_2021) => {
182 ($init, $init)
183 };
184}
185
186/// Creates a Boolean identity closure.
187///
188/// The generated closure applies logical negation twice, making it usable where
189/// a predicate function is required.
190#[macro_export]
191macro_rules! is_true {
192 () => {
193 |x| !!x
194 };
195}
196
197/// Creates a closure that negates a Boolean input.
198///
199/// The generated closure returns `!x` and can be passed directly to predicate
200/// combinators.
201#[macro_export]
202macro_rules! is_false {
203 () => {
204 |x| !x
205 };
206}
207
208/// Creates a closure that reports whether its input differs from zero.
209///
210/// The generated closure compares each input with the integer literal `0`.
211#[macro_export]
212macro_rules! is_nonzero {
213 () => {
214 |x| x != 0
215 };
216}
217
218/// Creates a closure that reports whether its input matches zero.
219///
220/// The generated closure uses a literal pattern through `is_matching!`.
221#[macro_export]
222macro_rules! is_zero {
223 () => {
224 $crate::is_matching!(0)
225 };
226}
227
228/// Creates a closure that compares each input with a supplied value for
229/// equality.
230///
231/// The comparison target remains inside the closure body and is evaluated on
232/// every call.
233#[macro_export]
234macro_rules! is_equal_to {
235 ($val:ident) => {
236 |x| x == $val
237 };
238
239 ($val:expr_2021) => {
240 |x| x == $val
241 };
242}
243
244/// Creates a closure that compares each input with a supplied value for
245/// inequality.
246///
247/// The comparison target remains inside the closure body and is evaluated on
248/// every call.
249#[macro_export]
250macro_rules! is_not_equal_to {
251 ($val:ident) => {
252 |x| x != $val
253 };
254
255 ($val:expr_2021) => {
256 |x| x != $val
257 };
258}
259
260/// Creates a closure that reports whether each input is less than a supplied
261/// value.
262///
263/// The comparison target remains inside the closure body and is evaluated on
264/// every call.
265#[macro_export]
266macro_rules! is_less_than {
267 ($val:ident) => {
268 |x| x < $val
269 };
270
271 ($val:expr_2021) => {
272 |x| x < $val
273 };
274}
275
276/// Creates a closure that tests its input with a `matches!` pattern.
277///
278/// The supplied tokens can contain any pattern form accepted by `matches!`. The
279/// closure returns false when the input does not match.
280#[macro_export]
281macro_rules! is_matching {
282 ($val:ident) => {
283 |x| matches!(x, $val)
284 };
285
286 ($($val:tt)+) => {
287 |x| matches!(x, $($val)+)
288 };
289}
290
291/// Creates a two-argument closure that compares its inputs for equality.
292///
293/// The generated closure returns the result of `a == b`.
294#[macro_export]
295macro_rules! is_equal {
296 () => {
297 |a, b| a == b
298 };
299}
300
301/// Creates a closure that dereferences an indexed tuple field.
302///
303/// The tuple argument is received by value, and the selected field is returned
304/// through unary dereference.
305#[macro_export]
306macro_rules! deref_at {
307 ($idx:tt) => {
308 |t| *t.$idx
309 };
310}
311
312/// Creates a closure that borrows an indexed tuple field.
313///
314/// The generated `ref` pattern borrows the tuple argument before returning a
315/// reference to the selected field.
316#[macro_export]
317macro_rules! ref_at {
318 ($idx:tt) => {
319 |ref t| &t.$idx
320 };
321}
322
323/// Creates a closure that returns an indexed field from a referenced tuple by
324/// value.
325///
326/// The generated pattern destructures the shared reference before selecting the
327/// field. Moving the tuple from that reference therefore requires a copyable
328/// value.
329#[macro_export]
330macro_rules! val_at {
331 ($idx:tt) => {
332 |&t| t.$idx
333 };
334}
335
336/// Creates a closure that selects an indexed tuple field by value.
337///
338/// The generated closure consumes its tuple argument and returns the selected
339/// field.
340#[macro_export]
341macro_rules! at {
342 ($idx:tt) => {
343 |t| t.$idx
344 };
345}