//! How to handle config files and arguments.
// TODO: Break this apart or do something a bit smarter.
pub mod args;
pub mod config;
use std::{convert::TryInto, str::FromStr, time::Instant};
use anyhow::{Context, Result};
use hashbrown::{HashMap, HashSet};
use indexmap::IndexSet;
use regex::Regex;
#[cfg(feature = "battery")]
use starship_battery::Manager;
use self::{
args::StringOrNum,
config::{layout::Row, ConfigV2, IgnoreList},
};
use crate::{
app::{filter::Filter, layout_manager::*, *},
canvas::{styling::CanvasStyling, ColourScheme},
constants::*,
data_collection::temperature::TemperatureType,
utils::{
data_units::DataUnit,
error::{self, BottomError},
},
widgets::*,
};
pub fn init_app(
config: ConfigV2, widget_layout: &BottomLayout, default_widget_id: u64,
default_widget_type_option: &Option<BottomWidgetType>, styling: &CanvasStyling,
) -> Result<App> {
use BottomWidgetType::*;
let retention_ms = get_retention(&config).context("Update `retention` in your config file.")?;
let autohide_time = config.general.args.autohide_time.unwrap_or(false);
let default_time_value = get_default_time_value(&config, retention_ms)?;
let use_basic_mode = config.general.args.basic.unwrap_or(false);
let expanded_upon_startup = config.general.args.expanded.unwrap_or(false);
// For processes
let is_grouped = config.process.args.group_processes.unwrap_or(false);
let is_case_sensitive = config.process.args.case_sensitive.unwrap_or(false);
let is_match_whole_word = config.process.args.whole_word.unwrap_or(false);
let is_use_regex = config.process.args.regex.unwrap_or(false);
let show_memory_as_values = config.process.args.mem_as_value.unwrap_or(false);
let is_default_tree = config.process.args.tree.unwrap_or(false);
let is_default_command = config.process.args.process_command.unwrap_or(false);
let is_advanced_kill = !(config.process.args.disable_advanced_kill.unwrap_or(false));
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_map: HashMap<u64, NetWidgetState> = HashMap::new();
let mut proc_state_map: HashMap<u64, ProcWidgetState> = HashMap::new();
let mut temp_state_map: HashMap<u64, TempWidgetState> = HashMap::new();
let mut disk_state_map: HashMap<u64, DiskTableWidget> = HashMap::new();
let mut battery_state_map: HashMap<u64, BatteryWidgetState> = HashMap::new();
let autohide_timer = if autohide_time {
Some(Instant::now())
} else {
None
};
let mut initial_widget_id: u64 = default_widget_id;
let mut initial_widget_type = Proc;
let is_custom_layout = config.row.is_some();
let mut used_widget_set = HashSet::new();
let network_unit_type = if config.network.args.network_use_bytes.unwrap_or(false) {
DataUnit::Byte
} else {
DataUnit::Bit
};
let network_scale_type = if config.network.args.network_use_log.unwrap_or(false) {
AxisScaling::Log
} else {
AxisScaling::Linear
};
let network_use_binary_prefix = config
.network
.args
.network_use_binary_prefix
.unwrap_or(false);
let proc_columns: Option<IndexSet<ProcWidgetColumn>> = {
let columns = config.process.columns.as_ref();
match columns {
Some(columns) => {
if columns.is_empty() {
None
} else {
Some(IndexSet::from_iter(columns.clone()))
}
}
None => None,
}
};
// TODO: Can probably just reuse the options struct.
let app_config_fields = AppConfigFields {
update_rate: get_update_rate(&config)?,
temperature_type: get_temperature(&config)?,
show_average_cpu: !config.cpu.args.hide_avg_cpu.unwrap_or(false),
use_dot: config.general.args.dot_marker.unwrap_or(false),
left_legend: config.cpu.args.left_legend.unwrap_or(false),
use_current_cpu_total: config.process.args.current_usage.unwrap_or(false),
unnormalized_cpu: config.process.args.unnormalized_cpu.unwrap_or(false),
use_basic_mode,
default_time_value,
time_interval: get_time_interval(&config, ret