Skip to main content

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}