//! How to handle config files and arguments.
// TODO: Break this apart or do something a bit smarter.
pub mod args;
pub mod colours;
pub mod config;
use std::{
convert::TryInto,
str::FromStr,
time::{Duration, Instant},
};
use anyhow::{Context, Result};
pub use colours::ConfigColours;
pub use config::ConfigV1;
use hashbrown::{HashMap, HashSet};
use indexmap::IndexSet;
use regex::Regex;
#[cfg(feature = "battery")]
use starship_battery::Manager;
use self::{
args::BottomArgs,
config::{layout::Row, IgnoreList, StringOrNum},
};
use crate::{
app::{filter::Filter, layout_manager::*, *},
canvas::{components::time_chart::LegendPosition, styling::CanvasStyling, ColourScheme},
constants::*,
data_collection::temperature::TemperatureType,
utils::{
data_units::DataUnit,
error::{self, BottomError, ConfigError, ConfigResult},
},
widgets::*,
};
macro_rules! is_flag_enabled {
($flag_name:ident, $arg:expr, $config:expr) => {
if $arg.$flag_name {
true
} else if let Some(flags) = &$config.flags {
flags.$flag_name.unwrap_or(false)
} else {
false
}
};
($cmd_flag:literal, $cfg_flag:ident, $matches:expr, $config:expr) => {
if $matches.get_flag($cmd_flag) {
true
} else if let Some(flags) = &$config.flags {
flags.$cfg_flag.unwrap_or(false)
} else {
false
}
};
}
pub fn init_app(
args: BottomArgs, config: ConfigV1, styling: &CanvasStyling,
) -> Result<(App, BottomLayout)> {
use BottomWidgetType::*;
// Since everything takes a reference, but we want to take ownership here to drop matches/config later...
let args = &args;
let config = &config;
let (widget_layout, default_widget_id, default_widget_type_option) =
get_widget_layout(args, config)
.context("Found an issue while trying to build the widget layout.")?;
let retention_ms = get_retention(args, config)?;
let autohide_time = is_flag_enabled!(autohide_time, args.general, config);
let default_time_value = get_default_time_value(args, config, retention_ms)?;
let use_basic_mode = is_flag_enabled!(basic, args.general, config);
let expanded = is_flag_enabled!(expanded, args.general, config);
// For processes
let is_grouped = is_flag_enabled!(group_processes, args.process, config);
let is_case_sensitive = is_flag_enabled!(case_sensitive, args.process, config);
let is_match_whole_word = is_flag_enabled!(whole_word, args.process, config);
let is_use_regex = is_flag_enabled!(regex, args.process, config);
let is_default_tree = is_flag_enabled!(tree, args.process, config);
let is_default_command = is_flag_enabled!(process_command, args.process, config);
let is_advanced_kill = !(is_flag_enabled!(disable_advanced_kill, args.process, config));
let process_memory_as_value = is_flag_enabled!(process_memory_as_value, args.process, config);
let mut widget_map = HashMap::new();
let mut cpu_state_map: HashMap<u64, CpuWidgetState> = HashMap::new();
let mut mem_state_map: HashMap<u64, MemWidgetState> = HashMap::new();
let mut net_state