use std::time::Duration;
use std::time::SystemTime;
use std::time::UNIX_EPOCH;
use chrono::prelude::*;
const BELOW_RC: &str = "/.config/below/belowrc";
#[macro_export]
macro_rules! every_n {
($n:expr, $ex:expr) => {{
static COUNT: std::sync::atomic::AtomicU32 = std::sync::atomic::AtomicU32::new(0);
let p = COUNT.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
if p % ($n) == 0 {
$ex
}
}};
}
pub use every_n;
pub fn get_unix_timestamp(timestamp: SystemTime) -> u64 {
timestamp
.duration_since(SystemTime::UNIX_EPOCH)
.expect("SystemTime before UNIX EPOCH!")
.as_secs()
}
pub fn get_system_time(timestamp: u64) -> SystemTime {
UNIX_EPOCH + Duration::from_secs(timestamp)
}
fn convert(val: f64, base: f64, units: &[&'static str]) -> String {
if val < 1_f64 {
return format!("{:.1} {}", val, units[0]);
}
let exponent = std::cmp::min(
(val.ln() / base.ln()).floor() as i32,
(units.len() - 1) as i32,
);
let pretty_val = format!("{:.1}", val / base.powi(exponent))
.parse::<f64>()
.unwrap()
* 1_f64;
let unit = units[exponent as usize];
format!("{} {}", pretty_val, unit)
}
pub fn convert_bytes(val: f64) -> String {
const UNITS: &[&str] = &["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
convert(val, 1024_f64, UNITS)
}
pub fn convert_freq(val: u64) -> String {
const UNITS: &[&str] = &["Hz", "kHz", "MHz", "GHz", "THz", "PHz", "EHz", "ZHz", "YHz"];
let val_f64 = val as f64;
convert(val_f64, 1000_f64, UNITS)
}
pub fn convert_duration(val: u64) -> String {
const UNITS: &[&str] = &["us", "ms", "s"];
convert(val as f64, 1000_f64, UNITS)
}
pub fn get_prefix(collapsed: bool) -> &'static str {
if collapsed { "└+ " } else { "└─ " }
}
pub fn fold_string<F>(val: &str, width: usize, start_idx: usize, stop_filter: F) -> String
where
F: FnMut(char) -> bool,
{
let str_len = val.len();
if start_idx >= str_len || val[start_idx..].len() <= width || width <= 3 {
return val.into();
}
let first_symbo_pos = val[start_idx..].find(stop_filter).unwrap_or(str_len) + 1;
let mid_str_len = (width - 3) >> 1;
let front_len = std::cmp::min(first_symbo_pos, mid_str_len);
let front_string = val[..front_len].to_string();
let back_string = val[str_len - width + front_len + 3..].to_string();
format!("{}...{}", front_string, back_string)
}
pub fn timestamp_to_datetime(timestamp: &i64) -> String {
let naive = NaiveDateTime::from_timestamp_opt(timestamp.clone(), 0).unwrap();
let datetime = naive.and_utc();
datetime
.with_timezone(&Local)
.format("%Y-%m-%d %H:%M:%S")
.to_string()
}
pub fn systemtime_to_datetime(system_time: SystemTime) -> String {
timestamp_to_datetime(&(get_unix_timestamp(system_time) as i64))
}
pub fn is_cpu_significant(v: f64) -> Option<cursive::theme::BaseColor> {
if v > 100.0 {
Some(cursive::theme::BaseColor::Red)
} else {
None
}
}
pub fn get_belowrc_filename() -> String {
format!(
"{}{}",
std::env::var("HOME").expect("Fail to obtain HOME env var"),
BELOW_RC
)
}
pub fn get_belowrc_dump_section_key() -> &'static str {
"dump"
}
pub fn get_belowrc_cmd_section_key() -> &'static str {
"cmd"
}
pub fn get_belowrc_view_section_key() -> &'static str {
"view"
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_every_n() {
let mut v1 = Vec::new();
let mut v2 = Vec::new();
for i in 0..10 {
every_n!(2, v1.push(i));
every_n!(1 + 2, v2.push(i));
}
assert_eq!(v1, vec![0, 2, 4, 6, 8]);
assert_eq!(v2, vec![0, 3, 6, 9]);
}
#[test]
fn test_convert_bytes() {
assert_eq!(convert_bytes(0.0), "0.0 B".to_owned());
assert_eq!(convert_bytes(1_024.0), "1 KB".to_owned());
assert_eq!(convert_bytes(1_023.0), "1023 B".to_owned());
assert_eq!(convert_bytes(1_076.0), "1.1 KB".to_owned());
assert_eq!(convert_bytes(10_239.0), "10 KB".to_owned());
assert_eq!(convert_bytes(1024_f64.powi(2)), "1 MB".to_owned());
assert_eq!(convert_bytes(1024_f64.powi(2) - 1.0), "1024 KB".to_owned());
assert_eq!(convert_bytes(1024_f64.powi(3) - 1.0), "1024 MB".to_owned());
assert_eq!(convert_bytes(1024_f64.powi(3)), "1 GB".to_owned());
assert_eq!(convert_bytes(1024_f64.powi(4)), "1 TB".to_owned());
}
#[test]
fn test_convert_freq() {
assert_eq!(convert_freq(0), "0.0 Hz".to_owned());
assert_eq!(convert_freq(1_000), "1 kHz".to_owned());
assert_eq!(convert_freq(999), "999 Hz".to_owned());
assert_eq!(convert_freq(1_050), "1.1 kHz".to_owned());
assert_eq!(convert_freq(9_999), "10 kHz".to_owned());
assert_eq!(convert_freq(1_000_000), "1 MHz".to_owned());
assert_eq!(convert_freq(999_950_000), "1000 MHz".to_owned());
assert_eq!(convert_freq(1_000_000_000), "1 GHz".to_owned());
assert_eq!(convert_freq(1_000_000_000_000), "1 THz".to_owned());
}
}