Skip to main content

tuwunel_service/admin/
context.rs

1use std::{fmt, fmt::Debug, time::SystemTime};
2
3use futures::{
4	Future, FutureExt, TryFutureExt,
5	io::{AsyncWriteExt, BufWriter},
6	lock::Mutex,
7};
8use ruma::EventId;
9use tokio::time::Instant;
10use tuwunel_core::Result;
11
12use crate::Services;
13
14pub struct Context<'a> {
15	pub services: &'a Services,
16	pub body: &'a [&'a str],
17	pub timer: SystemTime,
18	pub reply_id: Option<&'a EventId>,
19	pub output: Mutex<BufWriter<Vec<u8>>>,
20}
21
22impl Context<'_> {
23	pub async fn write_timed_query<F, T>(&self, query: F) -> Result
24	where
25		F: Future<Output = T>,
26		T: Debug,
27	{
28		let timer = Instant::now();
29		let result = query.await;
30		let query_time = timer.elapsed();
31
32		self.write_string(format!(
33			"Query completed in {query_time:?}:\n\n```rs\n{result:#?}\n```"
34		))
35		.await
36	}
37
38	pub async fn write_timed_query_try<F, T>(&self, query: F) -> Result
39	where
40		F: Future<Output = Result<T>>,
41		T: Debug,
42	{
43		let timer = Instant::now();
44		let result = query.await?;
45		let query_time = timer.elapsed();
46
47		self.write_string(format!(
48			"Query completed in {query_time:?}:\n\n```rs\n{result:#?}\n```"
49		))
50		.await
51	}
52
53	pub fn write_fmt(
54		&self,
55		arguments: fmt::Arguments<'_>,
56	) -> impl Future<Output = Result> + Send + '_ + use<'_> {
57		let buf = format!("{arguments}");
58		self.write_string(buf)
59	}
60
61	#[inline]
62	pub async fn write_string(&self, s: String) -> Result { self.write_str(&s).await }
63
64	pub fn write_str<'a>(&'a self, s: &'a str) -> impl Future<Output = Result> + Send + 'a {
65		self.output.lock().then(async move |mut output| {
66			output
67				.write_all(s.as_bytes())
68				.map_err(Into::into)
69				.await
70		})
71	}
72}