Skip to main content

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}