snark_tool/procedure/basic_procedures/
counter.rs

1use 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                // like this because borrow checker
32                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) = props.get(&property_hash) {
39                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}