1mod record;
2mod summary;
3
4use std::io::{self, Read, Write};
5use std::io::{BufRead, BufReader};
6
7use harper_core::TokenKind;
8pub use record::Record;
9pub use record::RecordKind;
10use serde::Serialize;
11use serde_json::Serializer;
12pub use summary::Summary;
13
14#[derive(Debug, Clone, Eq, PartialEq)]
16pub struct Stats {
17 pub records: Vec<Record>,
18}
19
20impl Stats {
21 pub fn new() -> Self {
22 Self {
23 records: Vec::new(),
24 }
25 }
26
27 pub fn summarize(&self) -> Summary {
29 let mut summary = Summary::new();
30
31 for record in &self.records {
32 match &record.kind {
33 RecordKind::Lint { kind, context } => {
34 summary.inc_lint_count(*kind);
35
36 for tok in context {
37 if let TokenKind::Word(None) = tok.kind {
38 summary.inc_misspelled_count(&tok.content);
39 }
40 }
41 }
42 RecordKind::LintConfigUpdate(lint_group_config) => {
43 summary.final_config = lint_group_config.clone();
44 }
45 }
46 }
47
48 summary
49 }
50
51 pub fn write(&self, w: &mut impl Write) -> io::Result<()> {
54 for record in &self.records {
55 let mut serializer = Serializer::new(&mut *w);
56 record.serialize(&mut serializer)?;
57 writeln!(w)?;
58 }
59
60 Ok(())
61 }
62
63 pub fn read(r: &mut impl Read) -> io::Result<Self> {
67 let br = BufReader::new(r);
68 let mut records = Vec::new();
69
70 for line_res in br.lines() {
71 let line = line_res?;
72
73 let record: Record = serde_json::from_str(&line)?;
74 records.push(record);
75 }
76
77 Ok(Self { records })
78 }
79}
80
81impl Default for Stats {
82 fn default() -> Self {
83 Self::new()
84 }
85}