use hwloc2;
use regex;
#[cfg(feature = "gui")]
use eframe::egui;
pub fn cpu_brand_transform(brand: &str) -> String {
let re_amd = regex::Regex::new(r"^(AMD.*?)\s(\d+)-Core Processor$").unwrap();
if let Some(captures) = re_amd.captures(brand) {
return String::from(captures.get(1).unwrap().as_str());
}
let re_intel_core = regex::Regex::new(r"^Intel\(R\)\sCore\(TM\)\s(.*?)\sCPU @ (\d+)\.(\d+)GHz$").unwrap();
if let Some(captures) = re_intel_core.captures(brand) {
return format!("Intel Core {}", captures.get(1).unwrap().as_str());
}
let re_intel_hetero_core = regex::Regex::new(r"^\d+th Gen Intel\(R\)\sCore\(TM\)\s(i\d-\d+.?)$").unwrap();
if let Some(captures) = re_intel_hetero_core.captures(brand) {
return format!("Intel Core {}", captures.get(1).unwrap().as_str());
}
String::from(brand)
}
pub fn format_cache_size(bytes: u64, precision: usize) -> String {
let units = ["B", "k", "M", "G"];
let pow = (bytes as f64).log(1024.0).floor() as usize;
let pow = usize::min(pow, units.len() - 1);
let number = bytes as f64 / usize::pow(1024, pow as u32) as f64;
let number_str = format!("{:.prec$}", number, prec = precision);
format!("{}{}", number_str.trim_end_matches('0').trim_end_matches('.'), units[pow])
}
pub fn find_squarest_factors(count: usize) -> (usize, usize) {
if count == 0 {
return (0,0)
}
let sqrt_n = (count as f64).sqrt() as usize;
for short_side in (1..=sqrt_n).rev() {
if count % short_side == 0 {
return (short_side, count / short_side);
}
}
unreachable!("Any `count` is divisible by 1, so this will not be reached");
}
pub fn squarish_grid_dimensions(count: usize, horizontal: bool) -> (usize, usize) {
let (shorter, longer) = find_squarest_factors(count);
if horizontal {(shorter, longer)} else {(longer, shorter)}
}
#[cfg(feature = "gui")] pub fn truncate_and_add_ellipsis(s: &str, max_width: usize) -> String {
if s.chars().count() > max_width {
let truncated = s.chars().take(max_width - 3).collect::<String>();
format!("{}...", truncated)
} else {
s.to_string()
}
}
#[cfg(feature = "gui")]
pub trait ShorcutControllable {
fn focus_on_shortcut(self, ui: &egui::Ui, shortcut: egui::KeyboardShortcut) -> Self;
fn clicked_or_shortcut(&self, ui: &egui::Ui, shortcut: egui::KeyboardShortcut) -> bool;
fn shortcut(&self, ui: &egui::Ui, shortcut: egui::KeyboardShortcut) -> bool;
}
#[cfg(feature = "gui")]
impl ShorcutControllable for egui::Response {
fn focus_on_shortcut(self, ui: &egui::Ui, shortcut: egui::KeyboardShortcut) -> Self {
if ui.input_mut(|i| i.consume_shortcut(&shortcut)) {
self.request_focus();
}
self
}
fn clicked_or_shortcut(&self, ui: &egui::Ui, shortcut: egui::KeyboardShortcut) -> bool {
self.clicked() || ui.input_mut(|i| i.consume_shortcut(&shortcut))
}
fn shortcut(&self, ui: &egui::Ui, shortcut: egui::KeyboardShortcut) -> bool {
ui.input_mut(|i| i.consume_shortcut(&shortcut))
}
}
pub trait CpuSetExt {
fn union(&self, other: &Self) -> Self;
fn subtract(&self, other: &Self) -> Self;
fn intersection(&self, other: &Self) -> Self;
fn toggle(&mut self, bit: u32);
fn synchronize_removed_process_cores_into<'a, I>(&self, thread_cpusets: I)
where
I: Iterator<Item = &'a mut hwloc2::CpuSet>;
fn synchronize_removed_process_cores_into_opt<'a, I>(&self, thread_cpusets: I)
where
I: Iterator<Item = &'a mut Option<hwloc2::CpuSet>>;
fn synchronize_added_thread_cores_from<'a, I>(&mut self, thread_cpusets: I)
where
I: Iterator<Item = &'a hwloc2::CpuSet>;
fn synchronize_added_thread_cores_from_opt<'a, I>(&mut self, thread_cpusets: I)
where
I: Iterator<Item = &'a Option<hwloc2::CpuSet>>;
}
impl CpuSetExt for hwloc2::CpuSet {
fn union(&self, other: &Self) -> Self {
let mut result = self.clone();
for bit in other.clone() {
result.set(bit);
}
result
}
fn subtract(&self, other: &Self) -> Self {
let mut result = self.clone();
for bit in other.clone() {
result.unset(bit);
}
result
}
fn intersection(&self, other: &Self) -> Self {
let mut result = Self::new();
for bit in self.clone() {
if other.is_set(bit) {
result.set(bit);
}
}
result
}
fn toggle(&mut self, bit: u32) {
if self.is_set(bit) {
self.unset(bit);
} else {
self.set(bit);
}
}
fn synchronize_removed_process_cores_into<'a, I>(&self, thread_cpusets: I)
where I: Iterator<Item = &'a mut hwloc2::CpuSet>
{
for thread in thread_cpusets {
*thread = self.intersection(thread);
}
}
fn synchronize_removed_process_cores_into_opt<'a, I>(&self, thread_cpusets: I)
where I: Iterator<Item = &'a mut Option<hwloc2::CpuSet>>
{
self.synchronize_removed_process_cores_into(thread_cpusets.filter_map(|t| t.as_mut()));
}
fn synchronize_added_thread_cores_from<'a, I>(&mut self, thread_cpusets: I)
where I: Iterator<Item = &'a hwloc2::CpuSet>
{
for thread in thread_cpusets {
*self = self.union(thread);
}
}
fn synchronize_added_thread_cores_from_opt<'a, I>(&mut self, thread_cpusets: I)
where I: Iterator<Item = &'a Option<hwloc2::CpuSet>>
{
self.synchronize_added_thread_cores_from(thread_cpusets.filter_map(|t| t.as_ref()));
}
}