snark_tool/procedure/basic_procedures/
counter.rs1use std::collections::HashMap;
2use std::marker;
3
4use crate::graph::undirected::UndirectedGraph;
5use crate::procedure::helpers::config_helper;
6use crate::procedure::procedure::{GraphProperties, Procedure, Result};
7use crate::procedure::procedure_builder::{ConfigMap, ProcedureBuilder};
8
9struct CounterProcedure<G: UndirectedGraph> {
10 config: CounterProcedureConfig,
11 _ph: marker::PhantomData<G>,
12}
13
14pub struct CounterProcedureConfig {
15 print: bool,
16}
17
18pub struct CounterProcedureBuilder {}
19
20impl<G: UndirectedGraph> Procedure<G> for CounterProcedure<G> {
21 fn run(&self, graphs: &mut Vec<(G, GraphProperties)>) -> Result<()> {
22 println!("running counter procedure");
23 let mut props = HashMap::new();
24 for graph in graphs {
25 for property in graph.1.iter() {
26 if property.0 == "graph-index" {
27 continue;
28 }
29 let property_hash = (property.0, property.1.to_string());
30
31 let count_opt = props.get(&property_hash);
33 let mut count_opt_copy: Option<usize> = None;
34 if let Some(count) = count_opt {
35 count_opt_copy = Some(*count);
36 }
37
38 if let Some(count) = count_opt_copy {
40 props.insert(property_hash, count + 1);
41 } else {
42 props.insert(property_hash, 1);
43 }
44 }
45 }
46 if self.config.print() {
47 println!("count: ");
48 for prop in props.iter() {
49 println!(" {:?} : {}", prop.0, prop.1);
50 }
51 }
52 Ok(())
53 }
54}
55
56impl CounterProcedureConfig {
57 pub const PROC_TYPE: &'static str = "count";
58
59 pub fn new(print: bool) -> Self {
60 CounterProcedureConfig { print }
61 }
62
63 pub fn default() -> Self {
64 CounterProcedureConfig { print: true }
65 }
66
67 pub fn from_proc_config(config: &HashMap<String, serde_json::Value>) -> Result<Self> {
68 let print =
69 config_helper::resolve_value_or_default(&config, "print", true, Self::PROC_TYPE)?;
70
71 let result = CounterProcedureConfig { print };
72 Ok(result)
73 }
74
75 pub fn print(&self) -> bool {
76 self.print
77 }
78}
79
80impl<G: UndirectedGraph + 'static> ProcedureBuilder<G> for CounterProcedureBuilder {
81 fn build_from_map(&self, config: ConfigMap) -> Result<Box<dyn Procedure<G>>> {
82 let proc_config = CounterProcedureConfig::from_proc_config(&config)?;
83 Ok(Box::new(CounterProcedure {
84 config: proc_config,
85 _ph: marker::PhantomData,
86 }))
87 }
88}
89
90impl CounterProcedureBuilder {
91 pub fn build<G: UndirectedGraph + 'static>(
92 config: CounterProcedureConfig,
93 ) -> Box<dyn Procedure<G>> {
94 Box::new(CounterProcedure {
95 config,
96 _ph: marker::PhantomData,
97 })
98 }
99}