unibar/src/main.rs

131 lines
3.8 KiB
Rust

use std::str;
use clap::Parser;
// Common utilities/types
mod common;
// Bar Modules
mod bar_modules;
// Commandline parsing
#[derive(Parser, Debug)]
#[command(name = "unibar")]
#[command(version = "1.0")]
#[command(about = "Get string of info for a status bar")]
#[command(about, long_about = "A tool that returns variety of components in a string
suitable to use in a status bar")]
struct CommandlineArgs {
/// Name of the weather station
#[arg(short = 's', long, default_value = "khio")]
weather_station: String,
/// Use Metric units in weather data. Imperial units otherwise
#[arg(short = 'm', long)]
weather_metric: bool,
/// Show music progess
#[arg(short = 'p', long)]
music_progress: bool,
/// Show JSON data returned by query
#[arg(short = 'D', long)]
debug_json: bool,
/// Show ICON debug information
#[arg(short = 'I', long)]
debug_modules: bool,
}
//
// Application (Unibar)
//
#[derive(Clone)]
struct Unibar {
// acts :UnibarActions
opts: common::AppOptions,
}
impl Unibar {
// --------------------
fn run(&self) {
if self.opts.debug_json {
self.debug_msg("Debugging ...");
}
self.check_options();
// Set up a list of all modules to be used
let bar_modules_enabled: Vec<Box<dyn bar_modules::BarModuleActions>> = vec! [
Box::new(bar_modules::bar_module_weather::UnibarModuleWeather::new(self.opts.clone())),
Box::new(bar_modules::bar_module_music::UnibarModuleMusic::new(self.opts.clone())),
];
// Get module's part to be displayed in the bar
let mut parts = Vec::new();
for mut md in bar_modules_enabled {
let mut mod_parts = Vec::new();
// Each bar module implements following 3 steps:
// * Generate raw data with pertinent information
// * Return a unicode icon to be displayed
// * Return a String content to be displayed after the icon
//
// Following generates ICON+CONTENT string for a module to be displayed
// in the bar
md.generate_data();
mod_parts.push(md.get_icon());
mod_parts.push(md.get_content());
parts.push(mod_parts.join(" "));
}
// Show module debug information if enabled
if self.opts.debug_modules {
let bar_modules_debugged: Vec<Box<dyn bar_modules::BarModuleDebug>> = vec! [
Box::new(bar_modules::bar_module_weather::UnibarModuleWeather::new(self.opts.clone())),
Box::new(bar_modules::bar_module_music::UnibarModuleMusic::new(self.opts.clone())),
];
for md in bar_modules_debugged {
md.post_debug();
}
}
// Print parts provided by each module
println!("{}", parts.join(" "));
}
// --------------------
fn check_options(&self) -> bool {
let all_good = true;
// If there are option checks to be added, make all_good a
// mutable var and update its status
return all_good;
}
// --------------------
fn debug_msg(&self, msg: &str) {
println!("[Debug ] -----> {}", msg);
}
}
//
// Entry point
//
fn main() {
let cmd_args = CommandlineArgs::parse();
let app = Unibar {
opts: common::AppOptions {
weather_units: if cmd_args.weather_metric { common::TemperatureUnits::Metric }
else { common::TemperatureUnits::Imperial },
weather_station: cmd_args.weather_station,
music_progress: cmd_args.music_progress,
debug_json: cmd_args.debug_json,
debug_modules: cmd_args.debug_modules
},
};
app.run();
}
// References:
// https://reintech.io/blog/working-with-json-in-rust