1use rayon::{
2 iter::FromParallelIterator,
3 prelude::{IntoParallelRefIterator, ParallelIterator},
4};
5use serde::Serialize;
6use std::{collections::HashMap, io::Write, iter::FromIterator};
7
8use crate::Output;
9
10use super::{Message, Stats};
11
12#[derive(Serialize, Debug)]
14pub struct Json {
15 total: Stats,
16 summary: HashMap<String, Result<Stats, String>>,
17}
18
19impl Output for Json {
20 type Options = ();
21 type Error = serde_json::Error;
22 fn to_writer<W: Write>(self, _: Self::Options, writter: W) -> serde_json::Result<()> {
23 serde_json::to_writer(writter, &self)
24 }
25}
26
27impl FromIterator<Message> for Json {
28 fn from_iter<T: IntoIterator<Item = Message>>(iter: T) -> Self {
29 let summary: HashMap<_, _> = iter.into_iter().collect();
30 let total = summary
31 .iter()
32 .flat_map(|(_, y)| y)
33 .cloned()
34 .fold(Stats::identity(), |x, y| x + y);
35 Json { total, summary }
36 }
37}
38
39impl FromParallelIterator<Message> for Json {
40 fn from_par_iter<I>(par_iter: I) -> Self
41 where
42 I: rayon::prelude::IntoParallelIterator<Item = Message>,
43 {
44 let summary: HashMap<_, _> = par_iter.into_par_iter().collect();
45 let total = summary
46 .par_iter()
47 .flat_map(|(_, y)| y)
48 .copied()
49 .reduce(Stats::identity, |x, y| x + y);
50 Json { total, summary }
51 }
52}