use anyhow::{Context, Result}; use clap::{clap_app, crate_authors, crate_description, crate_name, crate_version}; use serde::Deserialize; use std::collections::HashMap; use tracing::info; #[derive(Deserialize)] pub(crate) struct Config { pub(crate) hs_url: String, pub(crate) username: String, pub(crate) password: String, pub(crate) hosts: HashMap, pub(crate) store_path: String, } #[derive(Deserialize)] pub(crate) struct Host { pub(crate) mac_addr: [u8; 6], pub(crate) users: Vec, } pub(crate) fn setup_logging(level: u64) { let level = match level { 0 => log::LevelFilter::Error, 1 => log::LevelFilter::Warn, 2 => log::LevelFilter::Info, 3 => log::LevelFilter::Debug, _ => log::LevelFilter::Trace, }; match fern::Dispatch::new() .format(|out, message, record| { out.finish(format_args!( "[{}][{}][{}] {}", chrono::Local::now().format("%Y-%m-%d %H:%M:%S"), record.level(), record.target(), message )) }) .level(level) //This line is to avoid being flooded with event loop messages //(one per thread and second, so 12Hz for a hyperthreaded hexacore) //while running with LOG_LEVEL=debug .level_for("tokio_reactor", log::LevelFilter::Error) .level_for("tokio_core", log::LevelFilter::Error) .chain(std::io::stdout()) .apply() { Err(_) => { eprintln!("error setting up logging!"); } _ => info!("logging set up properly"), } } pub(crate) fn read_config(path: &str) -> Result { let config_file_content = std::fs::read_to_string(path).context("Couldn't read config file")?; Ok(toml::from_str(&config_file_content).context("Couldn't parse config file")?) } pub(crate) fn setup_clap() -> clap::ArgMatches<'static> { clap_app!(myapp => (name: crate_name!()) (version: crate_version!()) (author: crate_authors!()) (about: crate_description!()) (@arg config: +required "Set config file") (@arg v: -v --verbose ... "Be verbose (you can add this up to 4 times for more logs). By default, only errors are logged, so no output is a good thing.") ) .get_matches() }