Mercurial > lbo > hg > myi3stat
view src/main.rs @ 3:350cc212f07a
Move framework code to a separate module.
author | Lewin Bormann <lbo@spheniscida.de> |
---|---|
date | Sun, 14 Feb 2016 12:02:05 +0100 |
parents | be75e8a90861 |
children | ef523e637b3e |
line wrap: on
line source
mod framework; use std::collections::BTreeMap; use std::process; use std::env; extern crate getopts; use getopts::Options; use framework::*; /// Represents a/the set of metrics available for display. struct AvailableMetrics { metrics: BTreeMap<String, Box<Metric>>, opts: Options, } /// Set of all metrics. Used to register metrics and select the active ones based on the user's /// selection. impl AvailableMetrics { fn new() -> AvailableMetrics { let mut options = Options::new(); options.optopt("", "ordering", "Ordering of metrics in status bar. Comma-separated list of metric names \ (default ordering is ASCII-ordered, i.e. case sensitive)", "METRIC1,METRIC2,METRIC3"); options.optopt("", "interval", "Interval in seconds between individual render cycles. Default: 1", "SECONDS"); options.optflag("h", "help", "Print a help text"); AvailableMetrics { metrics: BTreeMap::new(), opts: options, } } /// Register a metric under the given name. /// desc and example are for the purpose of documenting the command line option that is added. /// Does fn register_metric(&mut self, name: &str, desc: &str, example: &str, metric: Box<Metric>) { if !self.metrics.contains_key(&String::from(name)) { self.opts.optopt("", name, desc, example); self.metrics.insert(String::from(name), metric); } } fn print_help(&self) { print!("{}", self.opts.usage("Usage: myi3stat [options]")); } fn parse_args(&mut self, args: &[String]) -> getopts::Matches { let matches = self.opts.parse(args); match matches { Err(_) => { self.print_help(); process::exit(1) } Ok(m) => m, } } /// Returns a map of metric -> position in ordering list fn make_ordering_map(ord_list: String) -> BTreeMap<String, i32> { let parts = ord_list.split(","); let mut i = 0; let mut ordmap = BTreeMap::new(); for metric in parts { ordmap.insert(String::from(metric), i); i += 1; } ordmap } /// Returns a vec of the selected metrics in the wanted order, and the interval between render /// cycles in seconds. fn evaluate(mut self, args: &[String]) -> (Vec<ActiveMetric>, i32) { let matches = self.parse_args(args); let mut metrics = Vec::new(); // Look for every defined metric if the user wants to have it displayed. for (metric_name, metric) in self.metrics.into_iter() { if matches.opt_present(&metric_name) { let st = metric.init(matches.opt_str(&metric_name)); metrics.push(ActiveMetric::new( String::from(metric_name), metric, st)); } } // Sort metrics by position in the supplied ordering list (or alternatively // alphabetically). let ordmap = AvailableMetrics::make_ordering_map(matches.opt_str("ordering") .unwrap_or(String::from(""))); metrics.sort_by(|a, b| { match (ordmap.get(a.name()), ordmap.get(b.name())) { (Some(i1), Some(i2)) => i1.cmp(i2), (_, _) => a.name().cmp(b.name()), } }); let interval = i32::from_str_radix(&matches.opt_str("interval") .unwrap_or(String::from("1")), 10) .unwrap_or(1); (metrics, interval) } } fn main() { let args: Vec<String> = env::args().collect(); let all_metrics = AvailableMetrics::new(); let (selected_metrics, interval) = all_metrics.evaluate(&args[1..]); }