tuwunel_service/admin/
context.rs1use 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}