rust_code_analysis_code_split/
count.rs1extern crate num_format;
2
3use num_format::{Locale, ToFormattedString};
4use std::fmt;
5use std::sync::{Arc, Mutex};
6
7use crate::traits::*;
8
9pub fn count<T: ParserTrait>(parser: &T, filters: &[String]) -> (usize, usize) {
12 let filters = parser.get_filters(filters);
13 let node = parser.get_root();
14 let mut cursor = node.cursor();
15 let mut stack = Vec::new();
16 let mut good = 0;
17 let mut total = 0;
18
19 stack.push(node);
20
21 while let Some(node) = stack.pop() {
22 total += 1;
23 if filters.any(&node) {
24 good += 1;
25 }
26 cursor.reset(&node);
27 if cursor.goto_first_child() {
28 loop {
29 stack.push(cursor.node());
30 if !cursor.goto_next_sibling() {
31 break;
32 }
33 }
34 }
35 }
36 (good, total)
37}
38
39#[derive(Debug)]
42pub struct CountCfg {
43 pub filters: Vec<String>,
45 pub stats: Arc<Mutex<Count>>,
47}
48
49#[derive(Debug, Default)]
51pub struct Count {
52 pub good: usize,
54 pub total: usize,
56}
57
58impl Callback for Count {
59 type Res = std::io::Result<()>;
60 type Cfg = CountCfg;
61
62 fn call<T: ParserTrait>(cfg: Self::Cfg, parser: &T) -> Self::Res {
63 let (good, total) = count(parser, &cfg.filters);
64 let mut results = cfg.stats.lock().unwrap();
65 results.good += good;
66 results.total += total;
67 Ok(())
68 }
69}
70
71impl fmt::Display for Count {
72 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
73 writeln!(
74 f,
75 "Total nodes: {}",
76 self.total.to_formatted_string(&Locale::en)
77 )?;
78 writeln!(
79 f,
80 "Found nodes: {}",
81 self.good.to_formatted_string(&Locale::en)
82 )?;
83 write!(
84 f,
85 "Percentage: {:.2}%",
86 (self.good as f64) / (self.total as f64) * 100.
87 )
88 }
89}