wz_fmt/
json.rs

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/// JSON representation of wz's output
13#[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}