frame_remote_externalities/
logging.rs1use std::{
19 future::Future,
20 io::{self, IsTerminal},
21 time::Instant,
22};
23
24use spinners::{Spinner, Spinners};
25
26use super::Result;
27
28pub(super) fn with_elapsed<F, R, EndMsg>(f: F, start_msg: &str, end_msg: EndMsg) -> Result<R>
32where
33 F: FnOnce() -> Result<R>,
34 EndMsg: FnOnce(&R) -> String,
35{
36 let timer = Instant::now();
37 let mut maybe_sp = start(start_msg);
38
39 Ok(end(f()?, timer, maybe_sp.as_mut(), end_msg))
40}
41
42pub(super) async fn with_elapsed_async<F, Fut, R, EndMsg>(
46 f: F,
47 start_msg: &str,
48 end_msg: EndMsg,
49) -> Result<R>
50where
51 F: FnOnce() -> Fut,
52 Fut: Future<Output = Result<R>>,
53 EndMsg: FnOnce(&R) -> String,
54{
55 let timer = Instant::now();
56 let mut maybe_sp = start(start_msg);
57
58 Ok(end(f().await?, timer, maybe_sp.as_mut(), end_msg))
59}
60
61fn start(start_msg: &str) -> Option<Spinner> {
62 let msg = format!("⏳ {start_msg}");
63
64 if io::stdout().is_terminal() {
65 Some(Spinner::new(Spinners::Dots, msg))
66 } else {
67 println!("{msg}");
68
69 None
70 }
71}
72
73fn end<T, EndMsg>(val: T, timer: Instant, maybe_sp: Option<&mut Spinner>, end_msg: EndMsg) -> T
74where
75 EndMsg: FnOnce(&T) -> String,
76{
77 let msg = format!("✅ {} in {:.2}s", end_msg(&val), timer.elapsed().as_secs_f32());
78
79 if let Some(sp) = maybe_sp {
80 sp.stop_with_message(msg);
81 } else {
82 println!("{msg}");
83 }
84
85 val
86}