Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
137 changes: 68 additions & 69 deletions src/config/deserialize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,74 @@ impl<'de: 'static> serde::Deserialize<'de> for super::Config {
None
};

let entries = config
.info
.map(|info| {
info.into_iter()
.map(|info| match info {
Entry::Info {
kind,
header,
value: format,
separator,
} => {
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::<Vec<_>>(),
header,
format,
separator: separator.unwrap_or_else(|| language_func("_colon_")),
}
}
Entry::Separator {
separator: content,
sizing: Some(sizing @ SeparatorSizing::Fixed(size)),
} => super::Entry::Separator {
content: content.chars().cycle().take(size).collect(),
sizing,
},
Entry::Separator { separator, sizing } => super::Entry::Separator {
content: separator,
sizing: sizing.unwrap_or_default(),
},
Entry::ColorBlocks {
color_block_style,
display,
} => super::Entry::ColorBlocks {
content: match color_block_style {
ColorBlockStyle::Circle => "● ",
ColorBlockStyle::Classic => "███",
ColorBlockStyle::Diamond => "◆ ",
ColorBlockStyle::Triangle => "▲ ",
ColorBlockStyle::Square => "■ ",
ColorBlockStyle::Star => "★ ",
ColorBlockStyle::Custom(content) => content,
},
display: match display {
Some(ColorBlockDisplay::Normal) => super::ColorBlockDisplay::Normal,
Some(ColorBlockDisplay::Bright) => super::ColorBlockDisplay::Bright,
_ => super::ColorBlockDisplay::Both,
},
},
})
.collect::<Vec<_>>()
})
.unwrap_or_else(|| super::default_entries(config.language));

Ok(Self {
info: super::group_fields_by_kind(&entries),
logo: config.logo,
language: config.language.into(),
colors: super::ColorOption {
Expand All @@ -137,75 +204,7 @@ impl<'de: 'static> serde::Deserialize<'de> for super::Config {
logo_color,
),
},
entries: config
.info
.map(|info| {
info.into_iter()
.map(|info| match info {
Entry::Info {
kind,
header,
value: format,
separator,
} => {
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::<Vec<_>>(),
header,
format,
separator: separator
.unwrap_or_else(|| language_func("_colon_")),
}
}
Entry::Separator {
separator: content,
sizing: Some(sizing @ SeparatorSizing::Fixed(size)),
} => super::Entry::Separator {
content: content.chars().cycle().take(size).collect(),
sizing,
},
Entry::Separator { separator, sizing } => super::Entry::Separator {
content: separator,
sizing: sizing.unwrap_or_default(),
},
Entry::ColorBlocks {
color_block_style,
display,
} => super::Entry::ColorBlocks {
content: match color_block_style {
ColorBlockStyle::Circle => "● ",
ColorBlockStyle::Classic => "███",
ColorBlockStyle::Diamond => "◆ ",
ColorBlockStyle::Triangle => "▲ ",
ColorBlockStyle::Square => "■ ",
ColorBlockStyle::Star => "★ ",
ColorBlockStyle::Custom(content) => content,
},
display: match display {
Some(ColorBlockDisplay::Normal) => {
super::ColorBlockDisplay::Normal
}
Some(ColorBlockDisplay::Bright) => {
super::ColorBlockDisplay::Bright
}
_ => super::ColorBlockDisplay::Both,
},
},
})
.collect::<Vec<_>>()
})
.unwrap_or_else(|| super::default_entries(config.language)),
entries,
parameters: config
.parameters
.map(|info| super::InfoConfig {
Expand Down
26 changes: 22 additions & 4 deletions src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@
pub mod deserialize;

use crate::{
error::FetchInfosError,
error::FetchInfoError,
system::{InfoField, InfoKind},
translations::get_language,
util::colored::ColorWrapper,
};
use bitcode::{Decode, Encode};
use serde::Deserialize;
use std::collections::{HashMap, HashSet};

const FALLBACK_COLOR: Option<ColorWrapper> = Some(ColorWrapper::Rgb {
r: 255,
Expand All @@ -19,6 +20,7 @@ const FALLBACK_COLOR: Option<ColorWrapper> = Some(ColorWrapper::Rgb {

#[derive(Debug, Decode, Encode)]
pub struct Config {
pub info: HashMap<InfoKind, Vec<InfoField>>,
pub language: &'static str,
pub entries: Vec<Entry<'static>>,
pub colors: ColorOption,
Expand Down Expand Up @@ -180,9 +182,11 @@ impl From<Locale> for &str {

impl Default for Config {
fn default() -> Self {
let entries = default_entries(Locale::default());
Self {
info: group_fields_by_kind(&entries),
language: Locale::default().into(),
entries: default_entries(Locale::default()),
entries,
colors: ColorOption::default(),
logo: LogoStyle::default(),
parameters: InfoConfig::default(),
Expand All @@ -194,7 +198,7 @@ pub fn load_config() -> Config {
let cache_path = dirs::cache_dir()
.map(|p| p.join("afetch.bin"))
.ok_or_else(|| {
FetchInfosError::error_exit(
FetchInfoError::error_exit(
"An error occurred while retrieving the cache folder, \
please open an issue at: https://github.com/Asthowen/AFetch/issues/new \
so that we can solve your issue.",
Expand All @@ -211,7 +215,7 @@ pub fn load_config() -> Config {
let config_path = dirs::config_dir()
.map(|p| p.join("afetch").join("config.json"))
.ok_or_else(|| {
FetchInfosError::error_exit(
FetchInfoError::error_exit(
"An error occurred while retrieving the config folder, \
please open an issue at: https://github.com/Asthowen/AFetch/issues/new \
so that we can solve your issue.",
Expand Down Expand Up @@ -265,3 +269,17 @@ fn default_entries(locale: Locale) -> Vec<Entry<'static>> {
},
]
}

fn group_fields_by_kind(entries: &[Entry]) -> HashMap<InfoKind, Vec<InfoField>> {
let mut info = HashMap::new();

for entry in entries {
if let Entry::Info { kind, fields, .. } = entry {
info.entry(kind).or_insert_with(HashSet::new).extend(fields);
}
}

info.into_iter()
.map(|(kind, fields)| (*kind, fields.into_iter().collect()))
.collect()
}
8 changes: 4 additions & 4 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ pub enum ErrorType {
}

#[derive(Debug)]
pub struct FetchInfosError(pub ErrorType);
pub struct FetchInfoError(pub ErrorType);

impl FetchInfosError {
impl FetchInfoError {
pub const fn missing() -> Self {
Self(ErrorType::Missing)
}
Expand All @@ -28,13 +28,13 @@ impl FetchInfosError {
}
}

impl From<VarError> for FetchInfosError {
impl From<VarError> for FetchInfoError {
fn from(_: VarError) -> Self {
Self::missing()
}
}

impl From<std::io::Error> for FetchInfosError {
impl From<std::io::Error> for FetchInfoError {
fn from(error: std::io::Error) -> Self {
match error.kind() {
ErrorKind::NotFound | ErrorKind::PermissionDenied => Self::missing(),
Expand Down
50 changes: 25 additions & 25 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use afetch::config::{Config, Entry, LogoStyle, SeparatorSizing, load_config};
use afetch::error::{ErrorType, FetchInfosError};
use afetch::error::{ErrorType, FetchInfoError};
use afetch::logos::get_logo;
use afetch::system::battery::get_battery;
use afetch::system::cpu::get_cpu;
Expand All @@ -10,39 +10,41 @@ use afetch::system::kernel::get_kernel;
use afetch::system::loadavg::get_loadavg;
use afetch::system::memory::get_memory;
use afetch::system::uptime::get_uptime;
use afetch::system::{InfoFunction, InfoGroup, InfoKind, InfosResult};
use afetch::system::{InfoGroup, InfoKind, InfoResult};
use afetch::translations::get_language;
use afetch::util::colored::{ColorWrapper, ColorizeExt};
use afetch::util::count_str_length;
#[cfg(feature = "image")]
use afetch::util::print_picture;
use colored::Colorize;
use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
use std::collections::HashMap;
use std::fmt::Write;
use supports_unicode::supports_unicode;

fn main() -> Result<(), FetchInfosError> {
fn main() -> Result<(), FetchInfoError> {
let config: Config = load_config();
let language_func = get_language(config.language);

let results: Vec<Result<InfosResult, FetchInfosError>> = config
.entries
let results: HashMap<InfoKind, Result<InfoResult, FetchInfoError>> = config
.info
.par_iter()
.filter_map(|element| match element {
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(|(kind, fields)| {
(
*kind,
match kind {
InfoKind::Battery => get_battery(language_func, fields, &config),
InfoKind::Cpu => get_cpu(language_func, fields, &config),
InfoKind::Disk => get_disk(language_func, fields, &config),
InfoKind::Disks => get_disks(language_func, fields, &config),
InfoKind::Host => get_hostname(language_func, fields, &config),
InfoKind::Kernel => get_kernel(language_func, fields, &config),
InfoKind::Uptime => get_uptime(language_func, fields, &config),
InfoKind::Memory => get_memory(language_func, fields, &config),
InfoKind::Loadavg => get_loadavg(language_func, fields, &config),
},
)
})
.map(|(f, fields)| f(language_func, fields, &config))
.collect();

let logo = if supports_unicode() {
Expand Down Expand Up @@ -83,7 +85,7 @@ 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 entry in &config.entries {
let mut write_entry = |entry: String| {
#[cfg(feature = "image")]
Expand Down Expand Up @@ -115,7 +117,7 @@ fn main() -> Result<(), FetchInfosError> {
separator,
..
} => {
let result = match &results[i2] {
let result = match &results[kind] {
Ok(result) => result,
Err(error) => {
match &error.0 {
Expand Down Expand Up @@ -152,11 +154,9 @@ fn main() -> Result<(), FetchInfosError> {
};

match result {
InfosResult::Single(single) => format_and_write(single),
InfosResult::Several(elements) => elements.iter().for_each(format_and_write),
InfoResult::Single(single) => format_and_write(single),
InfoResult::Several(elements) => elements.iter().for_each(format_and_write),
}

i2 += 1;
}
Entry::Separator { content, sizing } => {
let formatted_separator = match sizing {
Expand Down
12 changes: 6 additions & 6 deletions src/system/battery.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
use crate::config::Config;
use crate::error::FetchInfosError;
use crate::error::FetchInfoError;
use crate::filtered_values;
use crate::system::{InfoField, InfoGroup, InfoValue, InfosResult};
use crate::system::{InfoField, InfoGroup, InfoResult, InfoValue};
use crate::util::format_time;
use starship_battery::units::time::second;

pub fn get_battery(
languages_func: fn(&str) -> &str,
fields: &[InfoField],
_config: &Config,
) -> Result<InfosResult, FetchInfosError> {
) -> Result<InfoResult, FetchInfoError> {
let mut batteries = starship_battery::Manager::new()
.map_err(|error| FetchInfosError::error(error.to_string()))?
.map_err(|error| FetchInfoError::error(error.to_string()))?
.batteries()
.map_err(|error| FetchInfosError::error(error.to_string()))?;
.map_err(|error| FetchInfoError::error(error.to_string()))?;

let mut batteries_info: Vec<InfoGroup> = Vec::new();

Expand Down Expand Up @@ -128,5 +128,5 @@ pub fn get_battery(
batteries_info.push(info_group);
}

Ok(InfosResult::Several(batteries_info))
Ok(InfoResult::Several(batteries_info))
}
Loading