cli_ui/prompt/
task_log.rs1#![allow(missing_docs)]
2use crate::styles::{paint, DIM, ERR, OK, WHITE};
9use std::io::Write;
10use std::sync::Mutex;
11
12const BAR: &str = "│";
13const STEP_OK: &str = "◇";
14const STEP_GREEN: &str = "◆";
15const STEP_ERR: &str = "■";
16
17pub struct TaskLog {
18 title: String,
19 limit: usize,
20 lines: Mutex<Vec<String>>,
21}
22
23pub fn task_log(title: impl Into<String>) -> TaskLog {
24 let t = TaskLog {
25 title: title.into(),
26 limit: 10,
27 lines: Mutex::new(Vec::new()),
28 };
29 t.render_intro();
30 t
31}
32
33impl TaskLog {
34 pub fn limit(mut self, n: usize) -> Self {
36 self.limit = n.max(1);
37 self
38 }
39
40 fn render_intro(&self) {
41 let mut out = std::io::stderr();
42 let _ = writeln!(out, "{}", paint(DIM, BAR));
43 let _ = writeln!(
44 out,
45 "{} {}",
46 paint(OK, STEP_GREEN),
47 paint(WHITE, &self.title)
48 );
49 let _ = writeln!(out, "{}", paint(DIM, BAR));
50 }
51
52 pub fn message(&self, msg: impl AsRef<str>) {
53 let mut lines = self.lines.lock().unwrap();
54 for ln in msg.as_ref().split('\n') {
55 lines.push(ln.to_string());
56 }
57 while lines.len() > self.limit {
59 lines.remove(0);
60 }
61 let mut out = std::io::stderr();
62 let _ = writeln!(out, "{} {}", paint(DIM, BAR), paint(DIM, msg.as_ref()));
63 }
64
65 pub fn success(&self, msg: impl AsRef<str>) {
66 let mut out = std::io::stderr();
67 let _ = writeln!(
68 out,
69 "{} {}",
70 paint(OK, STEP_OK),
71 paint(WHITE, msg.as_ref())
72 );
73 }
74
75 pub fn error(&self, msg: impl AsRef<str>) {
76 let mut out = std::io::stderr();
77 let _ = writeln!(
78 out,
79 "{} {}",
80 paint(ERR, STEP_ERR),
81 paint(ERR, msg.as_ref())
82 );
83 let lines = self.lines.lock().unwrap();
85 for ln in lines.iter() {
86 let _ = writeln!(out, "{} {}", paint(DIM, BAR), paint(DIM, ln));
87 }
88 }
89}