rig_tools/live.rs
1//! [`Live`]: where a running tool reports its output as it comes, for a
2//! host that shows it before the call ends or keeps it in case the call is
3//! stopped.
4
5use std::fmt;
6use std::sync::Arc;
7
8/// Where a running tool reports output as it comes, such as
9/// [`Shell`](crate::Shell)'s lines. Cloning shares the sink.
10///
11/// ```
12/// use std::sync::{Arc, Mutex};
13/// use rig_tools::Live;
14///
15/// let seen = Arc::new(Mutex::new(String::new()));
16/// let live = Live::new({
17/// let seen = seen.clone();
18/// move |text| seen.lock().map(|mut seen| seen.push_str(text)).unwrap_or_default()
19/// });
20/// live.line("building\n");
21/// assert_eq!(seen.lock().map(|seen| seen.clone()).ok().as_deref(), Some("building\n"));
22/// ```
23#[derive(Clone)]
24pub struct Live(Arc<dyn Fn(&str) + Send + Sync>);
25
26impl Live {
27 /// A sink that hands each piece of output to `report`, on the thread the
28 /// tool runs on: keep `report` quick.
29 pub fn new(report: impl Fn(&str) + Send + Sync + 'static) -> Self {
30 Self(Arc::new(report))
31 }
32
33 /// Reports `text`, the next piece of output: a line with its `\n`, or
34 /// the end of the output without one.
35 pub fn line(&self, text: &str) {
36 (self.0)(text);
37 }
38}
39
40impl fmt::Debug for Live {
41 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
42 f.write_str("Live")
43 }
44}