git_global/
report.rs

1//! Reporting for git-global.
2
3use std::collections::HashMap;
4use std::io::Write;
5
6use serde_json::json;
7
8use crate::repo::Repo;
9
10/// A report containing the results of a git-global subcommand.
11///
12/// Contains overall messages and per-repo messages.
13pub struct Report {
14    messages: Vec<String>,
15    repo_messages: HashMap<Repo, Vec<String>>,
16    repos: Vec<Repo>,
17    pad_repo_output: bool,
18}
19
20impl Report {
21    /// Create a new `Report` for the given `Repo`s..
22    pub fn new(repos: &[Repo]) -> Report {
23        let mut repo_messages: HashMap<Repo, Vec<String>> = HashMap::new();
24        for repo in repos {
25            repo_messages.insert(repo.clone(), Vec::new());
26        }
27        Report {
28            messages: Vec::new(),
29            repos: repos.to_owned(),
30            repo_messages,
31            pad_repo_output: false,
32        }
33    }
34
35    /// Declares the desire to separate output when showing per-repo messages.
36    ///
37    /// Sets flag that indicates a blank line should be inserted between
38    /// messages for different repos when printing per-repo output.
39    pub fn pad_repo_output(&mut self) {
40        self.pad_repo_output = true;
41    }
42
43    /// Adds a message that applies to the overall operation.
44    pub fn add_message(&mut self, message: String) {
45        self.messages.push(message);
46    }
47
48    /// Adds a message that applies to the given repo.
49    pub fn add_repo_message(&mut self, repo: &Repo, data_line: String) {
50        if let Some(item) = self.repo_messages.get_mut(repo) {
51            item.push(data_line)
52        }
53    }
54
55    /// Writes all result messages to the given writer, as text.
56    pub fn print<W: Write>(&self, writer: &mut W) {
57        for msg in self.messages.iter() {
58            writeln!(writer, "{}", msg).unwrap();
59        }
60        for repo in self.repos.iter() {
61            let messages = self.repo_messages.get(repo).unwrap();
62            if !messages.is_empty() {
63                writeln!(writer, "{}", repo).unwrap();
64                for line in messages.iter().filter(|l| !l.is_empty()) {
65                    writeln!(writer, "{}", line).unwrap();
66                }
67                if self.pad_repo_output {
68                    writeln!(writer).unwrap();
69                }
70            }
71        }
72    }
73
74    /// Writes all result messages to the given writer, as JSON.
75    pub fn print_json<W: Write>(&self, writer: &mut W) {
76        let mut repo_messages: HashMap<String, Vec<&String>> = HashMap::new();
77        for (repo, messages) in self.repo_messages.iter() {
78            let msgs = messages.iter().filter(|l| !l.is_empty());
79            repo_messages.insert(repo.path(), msgs.collect());
80        }
81        let json = json!({
82            "error": false,
83            "messages": self.messages,
84            "repo_messages": repo_messages
85        });
86        writeln!(writer, "{:#}", json).unwrap();
87    }
88}