Skip to main content

tuwunel_admin/
context.rs

1pub(crate) use core::{write as core_write, writeln as core_writeln};
2use std::ops::Deref;
3
4/// Drop-in replacement for [`core::write!`] that block-wraps the call so the
5/// `format_args!` temporary is dropped before any `.await`, keeping the
6/// resulting future `Send`. Sync callers see no behavior difference.
7///
8/// Workaround for a recurring footgun: `core::write!($self, "...", x).await`
9/// holds a `fmt::Arguments<'_>` temporary (containing `!Send` vtable pointers)
10/// across the await point, poisoning the dispatcher's `Send` bound. The
11/// block scope ends the temporary's lifetime before the future is awaited.
12///
13/// Escape hatch: [`core_write!`] is the unmodified macro.
14macro_rules! write {
15	($self:expr, $($arg:tt)*) => { { $crate::context::core_write!($self, $($arg)*) } };
16}
17
18/// Drop-in replacement for [`core::writeln!`]; see [`write!`] for rationale.
19macro_rules! writeln {
20	($self:expr $(, $($arg:tt)*)?) => {
21		{ $crate::context::core_writeln!($self $(, $($arg)*)?) }
22	};
23}
24
25/// Orphan-rule wrapper: `#[implement(crate::Context)]` on each handler emits
26/// an inherent impl, illegal on a foreign type.
27pub(crate) struct Context<'a>(&'a tuwunel_service::admin::Context<'a>);
28
29impl<'a> Context<'a> {
30	#[inline]
31	pub(crate) const fn new(inner: &'a tuwunel_service::admin::Context<'a>) -> Self {
32		Self(inner)
33	}
34}
35
36impl<'a> Deref for Context<'a> {
37	type Target = tuwunel_service::admin::Context<'a>;
38
39	#[inline]
40	fn deref(&self) -> &Self::Target { self.0 }
41}