Skip to main content

otto_cli/output/
tasks.rs

1use crate::output::{bold, command, info, muted};
2use std::io::Write;
3
4#[derive(Debug, Clone)]
5pub struct TaskRow {
6    pub name: String,
7    pub description: String,
8    pub command: String,
9}
10
11pub fn print_tasks(mut w: impl Write, rows: &[TaskRow]) -> std::io::Result<()> {
12    if rows.is_empty() {
13        writeln!(w, "{} {}", info("i"), muted("No tasks found."))?;
14        return Ok(());
15    }
16
17    let mut normalized = Vec::with_capacity(rows.len());
18
19    for row in rows {
20        let description = if row.description.trim().is_empty() {
21            String::new()
22        } else {
23            row.description.clone()
24        };
25
26        let command = if row.command.trim().is_empty() {
27            "-".to_string()
28        } else {
29            row.command.clone()
30        };
31
32        normalized.push(TaskRow {
33            name: row.name.clone(),
34            description,
35            command,
36        });
37    }
38
39    for (idx, row) in normalized.iter().enumerate() {
40        writeln!(w, "{}", bold(&row.name))?;
41
42        if !row.description.is_empty() {
43            writeln!(w, "  description: {}", &row.description)?;
44        }
45
46        writeln!(w, "  command: {}", command(&row.command),)?;
47
48        if idx + 1 < normalized.len() {
49            writeln!(w)?;
50        }
51    }
52
53    Ok(())
54}
55
56#[cfg(test)]
57mod tests {
58    use super::*;
59    use crate::output::style::set_color_enabled;
60
61    #[test]
62    fn print_tasks_empty() {
63        set_color_enabled(false);
64        let mut out = Vec::new();
65        print_tasks(&mut out, &[]).expect("print tasks");
66        let text = String::from_utf8(out).expect("utf8");
67        assert!(text.contains("No tasks found"));
68        set_color_enabled(true);
69    }
70
71    #[test]
72    fn print_tasks_rows() {
73        set_color_enabled(false);
74        let mut out = Vec::new();
75        let rows = vec![TaskRow {
76            name: "test".to_string(),
77            description: "run tests".to_string(),
78            command: "cargo test".to_string(),
79        }];
80        print_tasks(&mut out, &rows).expect("print tasks");
81        let text = String::from_utf8(out).expect("utf8");
82        assert!(text.contains("test"));
83        assert!(text.contains("command:"));
84        set_color_enabled(true);
85    }
86}