1use std::collections::HashMap;
4use std::io::Write;
5
6use serde_json::json;
7
8use crate::repo::Repo;
9
10pub 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 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 pub fn pad_repo_output(&mut self) {
40 self.pad_repo_output = true;
41 }
42
43 pub fn add_message(&mut self, message: String) {
45 self.messages.push(message);
46 }
47
48 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 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 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}