diff --git a/src/config/deserialize.rs b/src/config/deserialize.rs index d473066..5ffc80d 100644 --- a/src/config/deserialize.rs +++ b/src/config/deserialize.rs @@ -13,6 +13,20 @@ struct ConfigWrapper<'a> { colors: Color<'a>, #[serde(default)] logo: super::LogoStyle<'a>, + #[serde(default)] + parameters: Option>, +} + +#[derive(Debug, Deserialize)] +struct InfoConfig<'a> { + #[serde(default, borrow)] + disks: Option>, +} + +#[derive(Debug, Deserialize)] +struct DisksInfoConfig<'a> { + #[serde(default, borrow)] + exclude: Option>, } #[derive(Debug, Deserialize)] @@ -133,23 +147,27 @@ impl<'de: 'static> serde::Deserialize<'de> for super::Config { header, value: format, separator, - } => super::Entry::Info { - kind, - fields: kind - .get_fields() - .iter() - .filter(|field| { - format - .unwrap_or_else(|| kind.default_format()) - .contains(&field.to_string()) - }) - .copied() - .collect::>(), - header: header - .unwrap_or_else(|| language_func(kind.default_header())), - format: format.unwrap_or_else(|| kind.default_format()), - separator: separator.unwrap_or_else(|| language_func("_colon_")), - }, + } => { + let header = + header.unwrap_or_else(|| language_func(kind.default_header())); + let format = format.unwrap_or_else(|| kind.default_format()); + super::Entry::Info { + kind, + fields: kind + .get_fields() + .iter() + .filter(|field| { + let field_str = field.as_str(); + header.contains(field_str) || format.contains(field_str) + }) + .copied() + .collect::>(), + header, + format, + separator: separator + .unwrap_or_else(|| language_func("_colon_")), + } + } Entry::Separator { separator: content, sizing: Some(sizing @ SeparatorSizing::Fixed(size)), @@ -188,6 +206,17 @@ impl<'de: 'static> serde::Deserialize<'de> for super::Config { .collect::>() }) .unwrap_or_else(|| super::default_entries(config.language)), + parameters: config + .parameters + .map(|info| super::InfoConfig { + disks: info + .disks + .map(|disks| super::DisksInfoConfig { + exclude: disks.exclude.unwrap_or_default(), + }) + .unwrap_or_default(), + }) + .unwrap_or_default(), }) } } diff --git a/src/config/mod.rs b/src/config/mod.rs index 872bcbd..55cb819 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -23,6 +23,25 @@ pub struct Config { pub entries: Vec>, pub colors: ColorOption, pub logo: LogoStyle<'static>, + pub parameters: InfoConfig<'static>, +} + +#[derive(Debug, Default, Decode, Encode)] +pub struct InfoConfig<'a> { + pub disks: DisksInfoConfig<'a>, +} + +#[derive(Debug, Decode, Encode)] +pub struct DisksInfoConfig<'a> { + pub exclude: Vec<&'a str>, +} + +impl<'a> Default for DisksInfoConfig<'a> { + fn default() -> Self { + Self { + exclude: vec!["/boot", "/etc", "/snapd", "/docker"], + } + } } #[derive(Debug, Decode, Encode)] @@ -88,15 +107,19 @@ impl<'a> Entry<'a> { separator: Option<&'a str>, ) -> Self { let format = kind.default_format(); + let header = header.unwrap_or_else(|| language_func(kind.default_header())); Self::Info { kind, - header: header.unwrap_or_else(|| language_func(kind.default_header())), + header, format, separator: separator.unwrap_or_else(|| language_func("_colon_")), fields: kind .get_fields() .iter() - .filter(|field| format.contains(&field.to_string())) + .filter(|field| { + let field_str = field.as_str(); + format.contains(field_str) || header.contains(field_str) + }) .copied() .collect(), } @@ -162,6 +185,7 @@ impl Default for Config { entries: default_entries(Locale::default()), colors: ColorOption::default(), logo: LogoStyle::default(), + parameters: InfoConfig::default(), } } } diff --git a/src/main.rs b/src/main.rs index 72b9c79..59cc2b4 100755 --- a/src/main.rs +++ b/src/main.rs @@ -3,6 +3,8 @@ use afetch::error::{ErrorType, FetchInfosError}; use afetch::logos::get_logo; use afetch::system::battery::get_battery; use afetch::system::cpu::get_cpu; +use afetch::system::disk::get_disk; +use afetch::system::disks::get_disks; use afetch::system::host::get_hostname; use afetch::system::kernel::get_kernel; use afetch::system::loadavg::get_loadavg; @@ -27,18 +29,20 @@ fn main() -> Result<(), FetchInfosError> { .entries .par_iter() .filter_map(|element| match element { - Entry::Info { kind, .. } => match kind { - InfoKind::Battery => Some(get_battery as InfoFunction), - InfoKind::Cpu => Some(get_cpu as InfoFunction), - InfoKind::Host => Some(get_hostname as InfoFunction), - InfoKind::Kernel => Some(get_kernel as InfoFunction), - InfoKind::Uptime => Some(get_uptime as InfoFunction), - InfoKind::Memory => Some(get_memory as InfoFunction), - InfoKind::Loadavg => Some(get_loadavg as InfoFunction), + Entry::Info { kind, fields, .. } => match kind { + InfoKind::Battery => Some((get_battery as InfoFunction, fields)), + InfoKind::Cpu => Some((get_cpu as InfoFunction, fields)), + InfoKind::Disk => Some((get_disk as InfoFunction, fields)), + InfoKind::Disks => Some((get_disks as InfoFunction, fields)), + InfoKind::Host => Some((get_hostname as InfoFunction, fields)), + InfoKind::Kernel => Some((get_kernel as InfoFunction, fields)), + InfoKind::Uptime => Some((get_uptime as InfoFunction, fields)), + InfoKind::Memory => Some((get_memory as InfoFunction, fields)), + InfoKind::Loadavg => Some((get_loadavg as InfoFunction, fields)), }, _ => None, }) - .map(|f| f(language_func)) + .map(|(f, fields)| f(language_func, fields, &config)) .collect(); let logo = if supports_unicode() { @@ -78,8 +82,9 @@ fn main() -> Result<(), FetchInfosError> { let mut output: String = String::default(); let mut last_info_len = 0; + let mut i = 0; let mut i2 = 0; - for (i, entry) in config.entries.iter().enumerate() { + for entry in &config.entries { let mut write_entry = |entry: String| { #[cfg(feature = "image")] if matches!(config.logo, LogoStyle::Image { .. }) { @@ -98,6 +103,8 @@ fn main() -> Result<(), FetchInfosError> { if logo.is_none() { writeln!(output, "{entry}").ok(); } + + i += 1; }; match entry { @@ -122,19 +129,21 @@ fn main() -> Result<(), FetchInfosError> { }; let mut format_and_write = |info: &InfoGroup| { + let mut formatted_header = (*header).to_owned(); let mut formatted_info = (*value).to_owned(); for value in &info.values { - formatted_info = - formatted_info.replace(&format!("{{{}}}", value.field), &value.value); + let placeholder = format!("{{{}}}", value.field); + formatted_header = formatted_header.replace(&placeholder, &value.value); + formatted_info = formatted_info.replace(&placeholder, &value.value); } - last_info_len = count_str_length(header) + last_info_len = count_str_length(&formatted_header) + count_str_length(separator) + count_str_length(&formatted_info); formatted_info = format!( "{}{}{}", - header.custom_color_wrapper(header_color).bold(), + formatted_header.custom_color_wrapper(header_color).bold(), separator.custom_color_wrapper(header_separator_color), formatted_info.custom_color_wrapper(info_color) ); @@ -183,8 +192,8 @@ fn main() -> Result<(), FetchInfosError> { } if let Some((_, _, lines)) = &logo { - if config.entries.len() < lines.len() { - for logo_line in &lines[config.entries.len()..] { + if i < lines.len() { + for logo_line in &lines[i..] { writeln!(output, " {}{}", logo_line, "".white()).ok(); } } diff --git a/src/system/battery.rs b/src/system/battery.rs index 893978b..54ec7fe 100644 --- a/src/system/battery.rs +++ b/src/system/battery.rs @@ -1,9 +1,15 @@ +use crate::config::Config; use crate::error::FetchInfosError; +use crate::filtered_values; use crate::system::{InfoField, InfoGroup, InfoValue, InfosResult}; use crate::util::format_time; use starship_battery::units::time::second; -pub fn get_battery(languages_func: fn(&str) -> &str) -> Result { +pub fn get_battery( + languages_func: fn(&str) -> &str, + fields: &[InfoField], + _config: &Config, +) -> Result { let mut batteries = starship_battery::Manager::new() .map_err(|error| FetchInfosError::error(error.to_string()))? .batteries() @@ -13,99 +19,110 @@ pub fn get_battery(languages_func: fn(&str) -> &str) -> Result().round() as u64, languages_func)) - { - info_group.values.push(InfoValue { - field: InfoField::BatteryTimeToFull, - value: time_to_full, - }); + if fields.contains(&InfoField::BatteryTimeToFull) { + if let Some(time_to_full) = battery + .time_to_full() + .and_then(|time| format_time(time.get::().round() as u64, languages_func)) + { + info_group.values.push(InfoValue { + field: InfoField::BatteryTimeToFull, + value: time_to_full, + }); + } } - if let Some(time_to_empty) = battery - .time_to_empty() - .and_then(|time| format_time(time.get::().round() as u64, languages_func)) - { - info_group.values.push(InfoValue { - field: InfoField::BatteryTimeToEmpty, - value: time_to_empty, - }); + if fields.contains(&InfoField::BatteryTimeToEmpty) { + if let Some(time_to_empty) = battery + .time_to_empty() + .and_then(|time| format_time(time.get::().round() as u64, languages_func)) + { + info_group.values.push(InfoValue { + field: InfoField::BatteryTimeToEmpty, + value: time_to_empty, + }); + } } batteries_info.push(info_group); diff --git a/src/system/cpu.rs b/src/system/cpu.rs index b3bcc62..20df837 100644 --- a/src/system/cpu.rs +++ b/src/system/cpu.rs @@ -1,9 +1,15 @@ +use crate::config::Config; use crate::error::FetchInfosError; +use crate::filtered_values; use crate::system::{InfoField, InfoGroup, InfoValue, InfosResult}; use std::collections::HashSet; use sysinfo::{CpuRefreshKind, RefreshKind, System}; -pub fn get_cpu(_languages_func: fn(&str) -> &str) -> Result { +pub fn get_cpu( + _languages_func: fn(&str) -> &str, + fields: &[InfoField], + _config: &Config, +) -> Result { let system = System::new_with_specifics(RefreshKind::nothing().with_cpu(CpuRefreshKind::everything())); @@ -16,28 +22,16 @@ pub fn get_cpu(_languages_func: fn(&str) -> &str) -> Result &str, + fields: &[InfoField], + config: &Config, +) -> Result { + let mut disks_info: Vec = Vec::new(); + + for disk in Disks::new_with_refreshed_list().list() { + let mount_point = disk.mount_point().to_string_lossy().to_string(); + + if config + .parameters + .disks + .exclude + .iter() + .any(|ignore| mount_point.starts_with(ignore)) + { + continue; + } + + let disk_usage = disk.usage(); + disks_info.push(InfoGroup { + values: filtered_values!( + fields, + [ + ( + InfoField::DiskName, + disk.name().to_os_string().into_string().map_err(|_| { + FetchInfosError::error("Failed to convert disk name to String") + })? + ), + ( + InfoField::DiskAvailableSpace, + convert_to_readable_unity(disk.available_space() as f64) + ), + ( + InfoField::DiskUsedSpace, + convert_to_readable_unity( + (disk.total_space() - disk.available_space()) as f64 + ) + ), + ( + InfoField::DiskTotalSpace, + convert_to_readable_unity(disk.total_space() as f64) + ), + (InfoField::DiskMountPoint, mount_point.to_owned()), + ( + InfoField::DiskFileSystem, + disk.file_system().to_string_lossy().to_string() + ), + (InfoField::DiskIsReadOnly, disk.is_read_only().to_string()), + (InfoField::DiskIsRemovable, disk.is_removable().to_string()), + (InfoField::DiskKind, disk.kind().to_string()), + ( + InfoField::DiskWrittenSinceBoot, + convert_to_readable_unity(disk_usage.total_written_bytes as f64) + ), + ( + InfoField::DiskReadSinceBoot, + convert_to_readable_unity(disk_usage.total_read_bytes as f64) + ), + ] + ), + }); + } + + Ok(InfosResult::Several(disks_info)) +} diff --git a/src/system/disks.rs b/src/system/disks.rs new file mode 100644 index 0000000..8feea27 --- /dev/null +++ b/src/system/disks.rs @@ -0,0 +1,57 @@ +use crate::config::Config; +use crate::error::FetchInfosError; +use crate::filtered_values; +use crate::system::{InfoField, InfoGroup, InfoValue, InfosResult}; +use crate::util::convert_to_readable_unity; +use sysinfo::{DiskRefreshKind, Disks}; + +pub fn get_disks( + _languages_func: fn(&str) -> &str, + fields: &[InfoField], + config: &Config, +) -> Result { + let mut available_space = 0; + let mut total_space = 0; + let mut count = 0; + + for disk in + Disks::new_with_refreshed_list_specifics(DiskRefreshKind::nothing().with_storage()).list() + { + let mount_point = disk.mount_point().to_string_lossy().to_string(); + + if config + .parameters + .disks + .exclude + .iter() + .any(|ignore| mount_point.starts_with(ignore)) + { + continue; + } + + available_space += disk.available_space(); + total_space += disk.total_space(); + count += 1; + } + + Ok(InfosResult::Single(InfoGroup { + values: filtered_values!( + fields, + [ + (InfoField::DisksCount, count.to_string()), + ( + InfoField::DisksAvailableSpace, + convert_to_readable_unity(available_space as f64) + ), + ( + InfoField::DisksUsedSpace, + convert_to_readable_unity((total_space - available_space) as f64) + ), + ( + InfoField::DisksTotalSpace, + convert_to_readable_unity(total_space as f64) + ), + ] + ), + })) +} diff --git a/src/system/host.rs b/src/system/host.rs index 58a050b..06f94d1 100644 --- a/src/system/host.rs +++ b/src/system/host.rs @@ -1,19 +1,22 @@ +use crate::config::Config; use crate::error::FetchInfosError; +use crate::filtered_values; use crate::system::{InfoField, InfoGroup, InfoValue, InfosResult}; use whoami::fallible::hostname; use whoami::username; -pub fn get_hostname(_languages_func: fn(&str) -> &str) -> Result { +pub fn get_hostname( + _languages_func: fn(&str) -> &str, + fields: &[InfoField], + _config: &Config, +) -> Result { Ok(InfosResult::Single(InfoGroup { - values: vec![ - InfoValue { - field: InfoField::Username, - value: username(), - }, - InfoValue { - field: InfoField::Hostname, - value: hostname().unwrap_or_default(), - }, - ], + values: filtered_values!( + fields, + [ + (InfoField::Username, username()), + (InfoField::Hostname, hostname().unwrap_or_default()), + ] + ), })) } diff --git a/src/system/kernel.rs b/src/system/kernel.rs index a3b05a6..fb5ecbb 100644 --- a/src/system/kernel.rs +++ b/src/system/kernel.rs @@ -1,18 +1,24 @@ +use crate::config::Config; use crate::error::FetchInfosError; +use crate::filtered_values; use crate::system::{InfoField, InfoGroup, InfoValue, InfosResult}; use sysinfo::System; -pub fn get_kernel(_languages_func: fn(&str) -> &str) -> Result { +pub fn get_kernel( + _languages_func: fn(&str) -> &str, + fields: &[InfoField], + _config: &Config, +) -> Result { Ok(InfosResult::Single(InfoGroup { - values: vec![ - InfoValue { - field: InfoField::KernelVersion, - value: System::kernel_version().ok_or_else(FetchInfosError::missing)?, - }, - InfoValue { - field: InfoField::KernelLongVersion, - value: System::kernel_long_version(), - }, - ], + values: filtered_values!( + fields, + [ + ( + InfoField::KernelVersion, + System::kernel_version().ok_or_else(FetchInfosError::missing)? + ), + (InfoField::KernelLongVersion, System::kernel_long_version()), + ] + ), })) } diff --git a/src/system/loadavg.rs b/src/system/loadavg.rs index cd9cc7c..a18adc8 100644 --- a/src/system/loadavg.rs +++ b/src/system/loadavg.rs @@ -1,23 +1,23 @@ +use crate::config::Config; use crate::error::FetchInfosError; +use crate::filtered_values; use crate::system::{InfoField, InfoGroup, InfoValue, InfosResult}; use sysinfo::System; -pub fn get_loadavg(_languages_func: fn(&str) -> &str) -> Result { +pub fn get_loadavg( + _languages_func: fn(&str) -> &str, + fields: &[InfoField], + _config: &Config, +) -> Result { let loadavg = System::load_average(); Ok(InfosResult::Single(InfoGroup { - values: vec![ - InfoValue { - field: InfoField::LoadAvgOne, - value: loadavg.one.to_string(), - }, - InfoValue { - field: InfoField::LoadAvgFive, - value: loadavg.five.to_string(), - }, - InfoValue { - field: InfoField::LoadAvgFifteen, - value: loadavg.fifteen.to_string(), - }, - ], + values: filtered_values!( + fields, + [ + (InfoField::LoadAvgOne, loadavg.one.to_string()), + (InfoField::LoadAvgFive, loadavg.five.to_string()), + (InfoField::LoadAvgFifteen, loadavg.fifteen.to_string()), + ] + ), })) } diff --git a/src/system/memory.rs b/src/system/memory.rs index 64959d1..45e881f 100644 --- a/src/system/memory.rs +++ b/src/system/memory.rs @@ -1,42 +1,51 @@ +use crate::config::Config; use crate::error::FetchInfosError; +use crate::filtered_values; use crate::system::{InfoField, InfoGroup, InfoValue, InfosResult}; use crate::util::convert_to_readable_unity; use sysinfo::{MemoryRefreshKind, RefreshKind, System}; -pub fn get_memory(_languages_func: fn(&str) -> &str) -> Result { +pub fn get_memory( + _languages_func: fn(&str) -> &str, + fields: &[InfoField], + _config: &Config, +) -> Result { let system = System::new_with_specifics( RefreshKind::nothing().with_memory(MemoryRefreshKind::everything()), ); Ok(InfosResult::Single(InfoGroup { - values: vec![ - InfoValue { - field: InfoField::MemoryAvailable, - value: convert_to_readable_unity(system.available_memory() as f64), - }, - InfoValue { - field: InfoField::MemoryFree, - value: convert_to_readable_unity(system.free_memory() as f64), - }, - InfoValue { - field: InfoField::MemoryTotal, - value: convert_to_readable_unity(system.total_memory() as f64), - }, - InfoValue { - field: InfoField::MemoryUsed, - value: convert_to_readable_unity(system.used_memory() as f64), - }, - InfoValue { - field: InfoField::MemorySwapFree, - value: convert_to_readable_unity(system.free_swap() as f64), - }, - InfoValue { - field: InfoField::MemorySwapTotal, - value: convert_to_readable_unity(system.total_swap() as f64), - }, - InfoValue { - field: InfoField::MemorySwapUsage, - value: convert_to_readable_unity(system.used_swap() as f64), - }, - ], + values: filtered_values!( + fields, + [ + ( + InfoField::MemoryAvailable, + convert_to_readable_unity(system.available_memory() as f64) + ), + ( + InfoField::MemoryFree, + convert_to_readable_unity(system.free_memory() as f64) + ), + ( + InfoField::MemoryTotal, + convert_to_readable_unity(system.total_memory() as f64) + ), + ( + InfoField::MemoryUsed, + convert_to_readable_unity(system.used_memory() as f64) + ), + ( + InfoField::MemorySwapFree, + convert_to_readable_unity(system.free_swap() as f64) + ), + ( + InfoField::MemorySwapTotal, + convert_to_readable_unity(system.total_swap() as f64) + ), + ( + InfoField::MemorySwapUsage, + convert_to_readable_unity(system.used_swap() as f64) + ), + ] + ), })) } diff --git a/src/system/mod.rs b/src/system/mod.rs index 7b1b24f..f4822fd 100755 --- a/src/system/mod.rs +++ b/src/system/mod.rs @@ -1,22 +1,44 @@ +use crate::config::Config; use crate::error::FetchInfosError; use bitcode::{Decode, Encode}; use serde::Deserialize; pub mod battery; pub mod cpu; +pub mod disk; +pub mod disks; pub mod host; pub mod kernel; pub mod loadavg; pub mod memory; pub mod uptime; -pub type InfoFunction = fn(fn(&str) -> &str) -> Result; +pub type InfoFunction = + fn(fn(&str) -> &str, &[InfoField], &Config) -> Result; + +#[macro_export] +macro_rules! filtered_values { + ($fields:expr, [ $( ($field:expr, $value_expr:expr) ),* $(,)? ]) => {{ + let mut info: Vec = Vec::new(); + $( + if $fields.contains(&$field) { + info.push(InfoValue { + field: $field, + value: $value_expr, + }); + } + )* + info + }}; +} #[derive(Deserialize, Clone, Copy, Debug, Decode, Encode)] #[serde(rename_all = "snake_case")] pub enum InfoKind { Battery, Cpu, + Disk, + Disks, Host, Kernel, Loadavg, @@ -52,7 +74,25 @@ impl InfoKind { InfoField::CpuVendor, InfoField::CpuArch, ], - Self::Host => &[InfoField::Hostname], + Self::Disk => &[ + InfoField::DiskName, + InfoField::DiskAvailableSpace, + InfoField::DiskUsedSpace, + InfoField::DiskTotalSpace, + InfoField::DiskMountPoint, + InfoField::DiskIsRemovable, + InfoField::DiskIsReadOnly, + InfoField::DiskKind, + InfoField::DiskWrittenSinceBoot, + InfoField::DiskReadSinceBoot, + ], + Self::Disks => &[ + InfoField::DisksCount, + InfoField::DisksAvailableSpace, + InfoField::DisksUsedSpace, + InfoField::DisksTotalSpace, + ], + Self::Host => &[InfoField::Hostname, InfoField::Username], Self::Kernel => &[InfoField::KernelVersion, InfoField::KernelLongVersion], Self::Loadavg => &[ InfoField::LoadAvgOne, @@ -76,6 +116,8 @@ impl InfoKind { match self { Self::Battery => "{battery_state_of_charge}%", Self::Cpu => "{cpu_name}", + Self::Disk => "{disk_used_space} / {disk_total_space}", + Self::Disks => "{disks_used_space} / {disks_total_space}", Self::Host => "{username}@{hostname}", Self::Kernel => "{kernel_long_version}", Self::Memory => "{memory_used} / {memory_total}", @@ -88,6 +130,8 @@ impl InfoKind { match self { Self::Cpu => "cpu", Self::Battery => "battery", + Self::Disk => "disk", + Self::Disks => "disks", Self::Host => "host", Self::Kernel => "kernel", Self::Memory => "memory", @@ -97,7 +141,7 @@ impl InfoKind { } } -#[derive(Debug, Clone, Copy, Decode, Encode)] +#[derive(Debug, PartialEq, Clone, Copy, Decode, Encode)] pub enum InfoField { BatteryModel, BatteryCycleCount, @@ -120,6 +164,21 @@ pub enum InfoField { CpuFrequency, CpuVendor, CpuArch, + DiskName, + DiskAvailableSpace, + DiskUsedSpace, + DiskTotalSpace, + DiskMountPoint, + DiskFileSystem, + DiskIsRemovable, + DiskIsReadOnly, + DiskKind, + DiskWrittenSinceBoot, + DiskReadSinceBoot, + DisksCount, + DisksAvailableSpace, + DisksUsedSpace, + DisksTotalSpace, Hostname, KernelVersion, KernelLongVersion, @@ -137,49 +196,70 @@ pub enum InfoField { LoadAvgFifteen, } -impl std::fmt::Display for InfoField { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { +impl InfoField { + pub const fn as_str(&self) -> &'static str { match self { - Self::BatteryModel => write!(f, "battery_model"), - Self::BatteryCycleCount => write!(f, "battery_cycle_count"), - Self::BatterySerialNumber => write!(f, "battery_serial_number"), - Self::BatteryVendor => write!(f, "battery_vendor"), - Self::BatteryTechnology => write!(f, "battery_technology"), - Self::BatteryState => write!(f, "battery_state"), - Self::BatteryTemperature => write!(f, "battery_temperature"), - Self::BatteryStateOfHealth => write!(f, "battery_state_of_health"), - Self::BatteryStateOfCharge => write!(f, "battery_state_of_charge"), - Self::BatteryEnergy => write!(f, "battery_energy"), - Self::BatteryEnergyFull => write!(f, "battery_energy_full"), - Self::BatteryEnergyFullDesign => write!(f, "battery_energy_full_design"), - Self::BatteryEnergyRate => write!(f, "battery_energy_rate"), - Self::BatteryVoltage => write!(f, "battery_voltage"), - Self::BatteryTimeToFull => write!(f, "battery_time_to_full"), - Self::BatteryTimeToEmpty => write!(f, "battery_time_to_empty"), - Self::CpuName => write!(f, "cpu_name"), - Self::CpuUsage => write!(f, "cpu_usage"), - Self::CpuFrequency => write!(f, "cpu_frequency"), - Self::CpuVendor => write!(f, "cpu_vendor"), - Self::CpuArch => write!(f, "cpu_arch"), - Self::Hostname => write!(f, "hostname"), - Self::KernelVersion => write!(f, "kernel_version"), - Self::KernelLongVersion => write!(f, "kernel_long_version"), - Self::MemoryAvailable => write!(f, "memory_available"), - Self::MemoryFree => write!(f, "memory_free"), - Self::MemoryTotal => write!(f, "memory_total"), - Self::MemoryUsed => write!(f, "memory_used"), - Self::MemorySwapFree => write!(f, "memory_swap_free"), - Self::MemorySwapTotal => write!(f, "memory_swap_total"), - Self::MemorySwapUsage => write!(f, "memory_swap_usage"), - Self::Uptime => write!(f, "uptime"), - Self::Username => write!(f, "username"), - Self::LoadAvgOne => write!(f, "loadavg_one"), - Self::LoadAvgFive => write!(f, "loadavg_five"), - Self::LoadAvgFifteen => write!(f, "loadavg_fifteen"), + Self::BatteryModel => "battery_model", + Self::BatteryCycleCount => "battery_cycle_count", + Self::BatterySerialNumber => "battery_serial_number", + Self::BatteryVendor => "battery_vendor", + Self::BatteryTechnology => "battery_technology", + Self::BatteryState => "battery_state", + Self::BatteryTemperature => "battery_temperature", + Self::BatteryStateOfHealth => "battery_state_of_health", + Self::BatteryStateOfCharge => "battery_state_of_charge", + Self::BatteryEnergy => "battery_energy", + Self::BatteryEnergyFull => "battery_energy_full", + Self::BatteryEnergyFullDesign => "battery_energy_full_design", + Self::BatteryEnergyRate => "battery_energy_rate", + Self::BatteryVoltage => "battery_voltage", + Self::BatteryTimeToFull => "battery_time_to_full", + Self::BatteryTimeToEmpty => "battery_time_to_empty", + Self::CpuName => "cpu_name", + Self::CpuUsage => "cpu_usage", + Self::CpuFrequency => "cpu_frequency", + Self::CpuVendor => "cpu_vendor", + Self::CpuArch => "cpu_arch", + Self::DiskName => "disk_name", + Self::DiskAvailableSpace => "disk_available_space", + Self::DiskUsedSpace => "disk_used_space", + Self::DiskTotalSpace => "disk_total_space", + Self::DiskMountPoint => "disk_mount_point", + Self::DiskFileSystem => "disk_file_system", + Self::DiskIsRemovable => "disk_is_removable", + Self::DiskIsReadOnly => "disk_is_readonly", + Self::DiskKind => "disk_kind", + Self::DiskWrittenSinceBoot => "disk_written_since_boot", + Self::DiskReadSinceBoot => "disk_read_since_boot", + Self::DisksCount => "disks_count", + Self::DisksAvailableSpace => "disks_available_space", + Self::DisksUsedSpace => "disks_used_space", + Self::DisksTotalSpace => "disks_total_space", + Self::Hostname => "hostname", + Self::KernelVersion => "kernel_version", + Self::KernelLongVersion => "kernel_long_version", + Self::MemoryAvailable => "memory_available", + Self::MemoryFree => "memory_free", + Self::MemoryTotal => "memory_total", + Self::MemoryUsed => "memory_used", + Self::MemorySwapFree => "memory_swap_free", + Self::MemorySwapTotal => "memory_swap_total", + Self::MemorySwapUsage => "memory_swap_usage", + Self::Uptime => "uptime", + Self::Username => "username", + Self::LoadAvgOne => "loadavg_one", + Self::LoadAvgFive => "loadavg_five", + Self::LoadAvgFifteen => "loadavg_fifteen", } } } +impl std::fmt::Display for InfoField { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "{}", self.as_str()) + } +} + pub struct InfoValue { pub field: InfoField, pub value: String, diff --git a/src/system/uptime.rs b/src/system/uptime.rs index 6b9e831..210d9d2 100644 --- a/src/system/uptime.rs +++ b/src/system/uptime.rs @@ -1,14 +1,23 @@ +use crate::config::Config; use crate::error::FetchInfosError; +use crate::filtered_values; use crate::system::{InfoField, InfoGroup, InfoValue, InfosResult}; use crate::util::format_time; use sysinfo::System; -pub fn get_uptime(languages_func: fn(&str) -> &str) -> Result { +pub fn get_uptime( + languages_func: fn(&str) -> &str, + fields: &[InfoField], + _config: &Config, +) -> Result { Ok(InfosResult::Single(InfoGroup { - values: vec![InfoValue { - field: InfoField::Uptime, - value: format_time(System::uptime(), languages_func) - .ok_or_else(FetchInfosError::missing)?, - }], + values: filtered_values!( + fields, + [( + InfoField::Uptime, + format_time(System::uptime(), languages_func) + .ok_or_else(FetchInfosError::missing)? + ),] + ), })) } diff --git a/src/translations/english.rs b/src/translations/english.rs index d6620d7..40b4725 100755 --- a/src/translations/english.rs +++ b/src/translations/english.rs @@ -22,8 +22,7 @@ pub fn english(key: &str) -> &'static str { "cpu" => "CPU", "gpu" => "GPU", "network" => "Network", - "disk" => "Disk ", - "disk-1" => ": ", + "disk" => "Disk ({disk_mount_point})", "disks" => "Disks", "public-ip" => "Public IP", "desktop" => "Desktop", diff --git a/src/translations/french.rs b/src/translations/french.rs index 201f13f..8eed0ae 100755 --- a/src/translations/french.rs +++ b/src/translations/french.rs @@ -22,8 +22,7 @@ pub fn french(key: &str) -> &'static str { "cpu" => "CPU", "gpu" => "GPU", "network" => "Réseau", - "disk" => "Disque ", - "disk-1" => " : ", + "disk" => "Disque ({disk_mount_point})", "disks" => "Disques", "public-ip" => "IP publique", "desktop" => "Bureau", diff --git a/src/util/mod.rs b/src/util/mod.rs index 04f2ed1..ef8a086 100644 --- a/src/util/mod.rs +++ b/src/util/mod.rs @@ -72,11 +72,12 @@ pub fn convert_to_readable_unity>(size: T) -> String { return "0 B".to_owned(); } let base: f64 = size_converted.log10() / 1024_f64.log10(); - let mut result: String = format!("{:.1}", 1024_f64.powf(base - base.floor())) - .trim_end_matches(".0") - .to_owned(); - result.push_str(SUFFIX[base.floor() as usize]); - result + format!( + "{:.1} {}", + 1024_f64.powf(base.fract()), + SUFFIX[base.floor() as usize] + ) + .replace(".0", "") } #[cfg(feature = "image")]