reedline/
external_printer.rs

1//! To print messages while editing a line
2//!
3//! See example:
4//!
5//! ``` shell
6//! cargo run --example external_printer --features=external_printer
7//! ```
8#[cfg(feature = "external_printer")]
9use {
10    crossbeam::channel::{bounded, Receiver, SendError, Sender},
11    std::fmt::Display,
12};
13
14#[cfg(feature = "external_printer")]
15pub const EXTERNAL_PRINTER_DEFAULT_CAPACITY: usize = 20;
16
17/// An ExternalPrinter allows to print messages of text while editing a line.
18/// The message is printed as a new line, the line-edit will continue below the
19/// output.
20///
21/// ## Required feature:
22/// `external_printer`
23#[cfg(feature = "external_printer")]
24#[derive(Debug, Clone)]
25pub struct ExternalPrinter<T>
26where
27    T: Display,
28{
29    sender: Sender<T>,
30    receiver: Receiver<T>,
31}
32
33#[cfg(feature = "external_printer")]
34impl<T> ExternalPrinter<T>
35where
36    T: Display,
37{
38    /// Creates an ExternalPrinter to store lines with a max_cap
39    pub fn new(max_cap: usize) -> Self {
40        let (sender, receiver) = bounded::<T>(max_cap);
41        Self { sender, receiver }
42    }
43    /// Gets a Sender to use the printer externally by sending lines to it
44    pub fn sender(&self) -> Sender<T> {
45        self.sender.clone()
46    }
47    /// Receiver to get messages if any
48    pub fn receiver(&self) -> &Receiver<T> {
49        &self.receiver
50    }
51
52    /// Convenience method if the whole Printer is cloned, blocks if max_cap is reached.
53    ///
54    pub fn print(&self, line: T) -> Result<(), SendError<T>> {
55        self.sender.send(line)
56    }
57
58    /// Convenience method to get a line if any, doesn´t block.
59    pub fn get_line(&self) -> Option<T> {
60        self.receiver.try_recv().ok()
61    }
62}
63
64#[cfg(feature = "external_printer")]
65impl<T> Default for ExternalPrinter<T>
66where
67    T: Display,
68{
69    fn default() -> Self {
70        Self::new(EXTERNAL_PRINTER_DEFAULT_CAPACITY)
71    }
72}