mirror of
https://github.com/Cyrix126/gupaxx.git
synced 2024-12-22 06:39:21 +00:00
feat: improve hashrate and time display on Status tab
This commit is contained in:
parent
16281c8479
commit
2c2b5b2731
8 changed files with 216 additions and 126 deletions
|
@ -234,21 +234,21 @@ impl Status {
|
|||
RichText::new("P2Pool Block Mean").underline().color(BONE),
|
||||
)
|
||||
.on_hover_text(STATUS_SUBMENU_P2POOL_BLOCK_MEAN);
|
||||
ui.label(api.p2pool_block_mean.to_string());
|
||||
ui.label(api.p2pool_block_mean.display(false));
|
||||
ui.label(
|
||||
RichText::new("Your P2Pool Share Mean")
|
||||
.underline()
|
||||
.color(BONE),
|
||||
)
|
||||
.on_hover_text(STATUS_SUBMENU_P2POOL_SHARE_MEAN);
|
||||
ui.label(p2pool_share_mean.to_string());
|
||||
ui.label(p2pool_share_mean.display(false));
|
||||
ui.label(
|
||||
RichText::new("Your Solo Block Mean")
|
||||
.underline()
|
||||
.color(BONE),
|
||||
)
|
||||
.on_hover_text(STATUS_SUBMENU_SOLO_BLOCK_MEAN);
|
||||
ui.label(solo_block_mean.to_string());
|
||||
ui.label(solo_block_mean.display(false));
|
||||
} else {
|
||||
ui.label(
|
||||
RichText::new("Your P2Pool Hashrate")
|
||||
|
@ -261,21 +261,21 @@ impl Status {
|
|||
RichText::new("P2Pool Block Mean").underline().color(BONE),
|
||||
)
|
||||
.on_hover_text(STATUS_SUBMENU_P2POOL_BLOCK_MEAN);
|
||||
ui.label(api.p2pool_block_mean.to_string());
|
||||
ui.label(api.p2pool_block_mean.display(false));
|
||||
ui.label(
|
||||
RichText::new("Your P2Pool Share Mean")
|
||||
.underline()
|
||||
.color(BONE),
|
||||
)
|
||||
.on_hover_text(STATUS_SUBMENU_P2POOL_SHARE_MEAN);
|
||||
ui.label(api.p2pool_share_mean.to_string());
|
||||
ui.label(api.p2pool_share_mean.display(false));
|
||||
ui.label(
|
||||
RichText::new("Your Solo Block Mean")
|
||||
.underline()
|
||||
.color(BONE),
|
||||
)
|
||||
.on_hover_text(STATUS_SUBMENU_SOLO_BLOCK_MEAN);
|
||||
ui.label(api.solo_block_mean.to_string());
|
||||
ui.label(api.solo_block_mean.display(false));
|
||||
}
|
||||
})
|
||||
});
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use egui::{ScrollArea, Ui};
|
||||
use egui::{Label, ScrollArea, Ui};
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use crate::app::eframe_impl::ProcessStatesGui;
|
||||
|
@ -30,7 +30,7 @@ impl Status {
|
|||
states: &ProcessStatesGui,
|
||||
) {
|
||||
let width_column = ui.text_style_height(&TextStyle::Body) * 16.0;
|
||||
let height_column = width_column * 2.5;
|
||||
let height_column = width_column * 2.7;
|
||||
ui.style_mut().wrap_mode = Some(egui::TextWrapMode::Extend);
|
||||
// let width = ((ui.available_width() / 5.0) - (SPACE * 1.7500)).max(0.0);
|
||||
ScrollArea::vertical().show(ui, |ui| {
|
||||
|
@ -121,7 +121,14 @@ fn gupax(ui: &mut Ui, sys: &Arc<Mutex<Sys>>) {
|
|||
let sys = sys.lock().unwrap();
|
||||
ui.label(RichText::new("Uptime").underline().color(BONE))
|
||||
.on_hover_text(STATUS_GUPAX_UPTIME);
|
||||
ui.label(sys.gupax_uptime.to_string());
|
||||
// put some space for uptime so that when seconds appears every minutes, no label is moved.
|
||||
ui.add_sized(
|
||||
[
|
||||
0.0,
|
||||
(ui.text_style_height(&TextStyle::Body) + ui.spacing().item_spacing.y) * 1.5,
|
||||
],
|
||||
Label::new(sys.gupax_uptime.to_string()),
|
||||
);
|
||||
ui.label(RichText::new("Gupaxx CPU").underline().color(BONE))
|
||||
.on_hover_text(STATUS_GUPAX_CPU_USAGE);
|
||||
ui.label(sys.gupax_cpu_usage.to_string());
|
||||
|
@ -159,7 +166,14 @@ fn p2pool(
|
|||
let api = p2pool_api.lock().unwrap();
|
||||
ui.label(RichText::new("Uptime").underline().color(BONE))
|
||||
.on_hover_text(STATUS_P2POOL_UPTIME);
|
||||
ui.label(format!("{}", api.uptime));
|
||||
// put some space for uptime so that when seconds appears every minutes, no label is moved.
|
||||
ui.add_sized(
|
||||
[
|
||||
0.0,
|
||||
(ui.text_style_height(&TextStyle::Body) + ui.spacing().item_spacing.y) * 1.5,
|
||||
],
|
||||
Label::new(api.uptime.display(true)),
|
||||
);
|
||||
ui.label(RichText::new("Current Shares").underline().color(BONE))
|
||||
.on_hover_text(STATUS_P2POOL_CURRENT_SHARES);
|
||||
ui.label(api.sidechain_shares.to_string());
|
||||
|
@ -193,10 +207,7 @@ fn p2pool(
|
|||
.color(BONE),
|
||||
)
|
||||
.on_hover_text(STATUS_P2POOL_HASHRATE);
|
||||
ui.label(format!(
|
||||
"[{} H/s]\n[{} H/s]\n[{} H/s]",
|
||||
api.hashrate_15m, api.hashrate_1h, api.hashrate_24h
|
||||
));
|
||||
ui.label(&api.hashrate);
|
||||
ui.label(RichText::new("Miners Connected").underline().color(BONE))
|
||||
.on_hover_text(STATUS_P2POOL_CONNECTIONS);
|
||||
ui.label(format!("{}", api.connections));
|
||||
|
@ -240,17 +251,21 @@ fn xmrig_proxy(
|
|||
let api = xmrig_proxy_api.lock().unwrap();
|
||||
ui.label(RichText::new("Uptime").underline().color(BONE))
|
||||
.on_hover_text(STATUS_XMRIG_PROXY_UPTIME);
|
||||
ui.label(api.uptime.to_string());
|
||||
// put some space for uptime so that when seconds appears every minutes, no label is moved.
|
||||
ui.add_sized(
|
||||
[
|
||||
0.0,
|
||||
(ui.text_style_height(&TextStyle::Body) + ui.spacing().item_spacing.y) * 1.5,
|
||||
],
|
||||
Label::new(api.uptime.display(true)),
|
||||
);
|
||||
ui.label(
|
||||
RichText::new("Hashrate\n(1m/10m/1h/12h/24h)")
|
||||
.underline()
|
||||
.color(BONE),
|
||||
)
|
||||
.on_hover_text(STATUS_XMRIG_PROXY_HASHRATE);
|
||||
ui.label(format!(
|
||||
"[{} H/s]\n[{} H/s]\n[{} H/s]\n[{} H/s]\n[{} H/s]",
|
||||
api.hashrate_1m, api.hashrate_10m, api.hashrate_1h, api.hashrate_12h, api.hashrate_24h
|
||||
));
|
||||
ui.label(&api.hashrate);
|
||||
ui.label(format!(
|
||||
"[Accepted: {}]\n[Rejected: {}]",
|
||||
api.accepted, api.rejected
|
||||
|
@ -282,7 +297,14 @@ fn xmrig(
|
|||
let api = xmrig_api.lock().unwrap();
|
||||
ui.label(RichText::new("Uptime").underline().color(BONE))
|
||||
.on_hover_text(STATUS_XMRIG_UPTIME);
|
||||
ui.label(api.uptime.to_string());
|
||||
// put some space for uptime so that when seconds appears every minutes, no label is moved.
|
||||
ui.add_sized(
|
||||
[
|
||||
0.0,
|
||||
(ui.text_style_height(&TextStyle::Body) + ui.spacing().item_spacing.y) * 1.5,
|
||||
],
|
||||
Label::new(api.uptime.display(true)),
|
||||
);
|
||||
ui.label(api.resources.to_string());
|
||||
ui.label(
|
||||
RichText::new("Hashrate\n(10s/1m/15m)")
|
||||
|
@ -407,7 +429,14 @@ fn node(ui: &mut Ui, node_alive: bool, node_api: &Arc<Mutex<PubNodeApi>>) {
|
|||
let api = node_api.lock().unwrap();
|
||||
ui.label(RichText::new("Uptime").underline().color(BONE))
|
||||
.on_hover_text(STATUS_NODE_UPTIME);
|
||||
ui.label(api.uptime.to_string());
|
||||
// put some space for uptime so that when seconds appears every minutes, no label is moved.
|
||||
ui.add_sized(
|
||||
[
|
||||
0.0,
|
||||
(ui.text_style_height(&TextStyle::Body) + ui.spacing().item_spacing.y) * 1.5,
|
||||
],
|
||||
Label::new(api.uptime.display(true)),
|
||||
);
|
||||
|
||||
ui.label(RichText::new("Block Height").underline().color(BONE))
|
||||
.on_hover_text(STATUS_NODE_BLOCK_HEIGHT);
|
||||
|
|
|
@ -444,7 +444,7 @@ impl Helper {
|
|||
helper: &Helper,
|
||||
max_threads: u16,
|
||||
) {
|
||||
let gupax_uptime = helper.uptime.to_string();
|
||||
let gupax_uptime = helper.uptime.display(true);
|
||||
let cpu = &sysinfo.cpus()[0];
|
||||
let gupax_cpu_usage = format!(
|
||||
"{:.2}%",
|
||||
|
@ -793,14 +793,20 @@ fn signal_end(
|
|||
let uptime = HumanTime::into_human(start.elapsed());
|
||||
info!(
|
||||
"{} Watchdog | Stopped ... Uptime was: [{}], Exit status: [{}]",
|
||||
process.name, uptime, exit_status
|
||||
process.name,
|
||||
uptime.display(false),
|
||||
exit_status
|
||||
);
|
||||
// This is written directly into the GUI API, because sometimes the 900ms event loop can't catch it.
|
||||
let name = process.name.to_owned();
|
||||
if let Err(e) = writeln!(
|
||||
gui_api_output_raw,
|
||||
"{}\n{} stopped | Uptime: [{}] | Exit status: [{}]\n{}\n\n\n\n",
|
||||
name, HORI_CONSOLE, uptime, exit_status, HORI_CONSOLE
|
||||
name,
|
||||
HORI_CONSOLE,
|
||||
uptime.display(false),
|
||||
exit_status,
|
||||
HORI_CONSOLE
|
||||
) {
|
||||
error!(
|
||||
"{} Watchdog | GUI Uptime/Exit status write failed: {}",
|
||||
|
@ -831,14 +837,20 @@ fn signal_end(
|
|||
let uptime = HumanTime::into_human(start.elapsed());
|
||||
info!(
|
||||
"{} Watchdog | Stopped ... Uptime was: [{}], Exit status: [{}]",
|
||||
process.name, uptime, exit_status
|
||||
process.name,
|
||||
uptime.display(false),
|
||||
exit_status
|
||||
);
|
||||
// This is written directly into the GUI API, because sometimes the 900ms event loop can't catch it.
|
||||
let name = process.name.to_owned();
|
||||
if let Err(e) = writeln!(
|
||||
gui_api_output_raw,
|
||||
"{}\n{} stopped | Uptime: [{}] | Exit status: [{}]\n{}\n\n\n\n",
|
||||
name, HORI_CONSOLE, uptime, exit_status, HORI_CONSOLE
|
||||
name,
|
||||
HORI_CONSOLE,
|
||||
uptime.display(false),
|
||||
exit_status,
|
||||
HORI_CONSOLE
|
||||
) {
|
||||
error!(
|
||||
"{} Watchdog | GUI Uptime/Exit status write failed: {}",
|
||||
|
|
|
@ -706,9 +706,10 @@ pub struct PubP2poolApi {
|
|||
pub xmr_day: f64,
|
||||
pub xmr_month: f64,
|
||||
// Local API
|
||||
pub hashrate_15m: HumanNumber,
|
||||
pub hashrate_1h: HumanNumber,
|
||||
pub hashrate_24h: HumanNumber,
|
||||
pub hashrate: String,
|
||||
pub hashrate_15m: u64,
|
||||
pub hashrate_1h: u64,
|
||||
pub hashrate_24h: u64,
|
||||
pub shares_found: Option<u64>,
|
||||
pub average_effort: HumanNumber,
|
||||
pub current_effort: HumanNumber,
|
||||
|
@ -766,9 +767,10 @@ impl PubP2poolApi {
|
|||
xmr_hour: 0.0,
|
||||
xmr_day: 0.0,
|
||||
xmr_month: 0.0,
|
||||
hashrate_15m: HumanNumber::unknown(),
|
||||
hashrate_1h: HumanNumber::unknown(),
|
||||
hashrate_24h: HumanNumber::unknown(),
|
||||
hashrate: HumanNumber::from_hashrate(&[None, None, None]).to_string(),
|
||||
hashrate_15m: 0,
|
||||
hashrate_1h: 0,
|
||||
hashrate_24h: 0,
|
||||
shares_found: None,
|
||||
average_effort: HumanNumber::unknown(),
|
||||
current_effort: HumanNumber::unknown(),
|
||||
|
@ -940,9 +942,15 @@ impl PubP2poolApi {
|
|||
// Mutate [PubP2poolApi] with data from a [PrivP2poolLocalApi] and the process output.
|
||||
pub(super) fn update_from_local(public: &mut Self, local: PrivP2poolLocalApi) {
|
||||
*public = Self {
|
||||
hashrate_15m: HumanNumber::from_u64(local.hashrate_15m),
|
||||
hashrate_1h: HumanNumber::from_u64(local.hashrate_1h),
|
||||
hashrate_24h: HumanNumber::from_u64(local.hashrate_24h),
|
||||
hashrate: HumanNumber::from_hashrate(&[
|
||||
Some(local.hashrate_15m),
|
||||
Some(local.hashrate_1h),
|
||||
Some(local.hashrate_24h),
|
||||
])
|
||||
.to_string(),
|
||||
hashrate_15m: local.hashrate_15m,
|
||||
hashrate_1h: local.hashrate_1h,
|
||||
hashrate_24h: local.hashrate_24h,
|
||||
shares_found: Some(local.shares_found),
|
||||
average_effort: HumanNumber::to_percent(local.average_effort),
|
||||
current_effort: HumanNumber::to_percent(local.current_effort),
|
||||
|
|
|
@ -274,9 +274,9 @@ Uptime = 0h 2m 4s
|
|||
let mut p = public.lock().unwrap();
|
||||
PubP2poolApi::update_from_local(&mut p, local);
|
||||
println!("AFTER LOCAL: {:#?}", p);
|
||||
assert_eq!(p.hashrate_15m.to_string(), "10,000");
|
||||
assert_eq!(p.hashrate_1h.to_string(), "20,000");
|
||||
assert_eq!(p.hashrate_24h.to_string(), "30,000");
|
||||
assert_eq!(p.hashrate_15m.to_string(), "10000");
|
||||
assert_eq!(p.hashrate_1h.to_string(), "20000");
|
||||
assert_eq!(p.hashrate_24h.to_string(), "30000");
|
||||
assert_eq!(
|
||||
p.shares_found.expect("the value is set").to_string(),
|
||||
"1000"
|
||||
|
@ -297,14 +297,14 @@ Uptime = 0h 2m 4s
|
|||
assert_eq!(p.p2pool_hashrate.to_string(), "1.000 MH/s");
|
||||
assert_eq!(p.miners.to_string(), "1,000");
|
||||
assert_eq!(
|
||||
p.solo_block_mean.to_string(),
|
||||
"5 months\n21 days\n9 hours\n52 minutes"
|
||||
p.solo_block_mean.display(false),
|
||||
"5 months, 21 days, 9 hours, 52 minutes"
|
||||
);
|
||||
assert_eq!(
|
||||
p.p2pool_block_mean.to_string(),
|
||||
"3 days\n11 hours\n20 minutes"
|
||||
p.p2pool_block_mean.display(false),
|
||||
"3 days, 11 hours, 20 minutes"
|
||||
);
|
||||
assert_eq!(p.p2pool_share_mean.to_string(), "8 minutes\n20 seconds");
|
||||
assert_eq!(p.p2pool_share_mean.display(false), "8 minutes, 20 seconds");
|
||||
assert_eq!(p.p2pool_percent.to_string(), "0.040000%");
|
||||
assert_eq!(p.user_p2pool_percent.to_string(), "2.000000%");
|
||||
assert_eq!(p.user_monero_percent.to_string(), "0.000800%");
|
||||
|
|
|
@ -793,11 +793,16 @@ impl PubXmrigApi {
|
|||
Some(Some(h)) => *h,
|
||||
_ => 0.0,
|
||||
};
|
||||
|
||||
let total_hasrate = private
|
||||
.hashrate
|
||||
.total
|
||||
.iter()
|
||||
.map(|x| x.as_ref().map(|y| *y as u64))
|
||||
.collect::<Vec<Option<u64>>>();
|
||||
*public = Self {
|
||||
worker_id: private.worker_id,
|
||||
resources: HumanNumber::from_load(private.resources.load_average).to_string(),
|
||||
hashrate: HumanNumber::from_hashrate(private.hashrate.total).to_string(),
|
||||
hashrate: HumanNumber::from_hashrate(&total_hasrate).to_string(),
|
||||
diff: Unsigned::from(private.connection.diff as usize).to_string(),
|
||||
accepted: Unsigned::from(private.connection.accepted as usize).to_string(),
|
||||
rejected: Unsigned::from(private.connection.rejected as usize).to_string(),
|
||||
|
|
|
@ -12,7 +12,7 @@ use std::{
|
|||
};
|
||||
use tokio::spawn;
|
||||
|
||||
use crate::human::HumanTime;
|
||||
use crate::human::{HumanNumber, HumanTime};
|
||||
use crate::miscs::client;
|
||||
use crate::{
|
||||
GUPAX_VERSION_UNDERSCORE, UNKNOWN_DATA,
|
||||
|
@ -467,12 +467,14 @@ impl Helper {
|
|||
// sleep
|
||||
}
|
||||
}
|
||||
#[allow(unused)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct PubXmrigProxyApi {
|
||||
pub output: String,
|
||||
pub uptime: HumanTime,
|
||||
pub accepted: u32,
|
||||
pub rejected: u32,
|
||||
pub hashrate: String,
|
||||
pub hashrate_1m: f32,
|
||||
pub hashrate_10m: f32,
|
||||
pub hashrate_1h: f32,
|
||||
|
@ -493,6 +495,7 @@ impl PubXmrigProxyApi {
|
|||
uptime: HumanTime::new(),
|
||||
accepted: 0,
|
||||
rejected: 0,
|
||||
hashrate: HumanNumber::from_hashrate(&[None, None, None, None, None, None]).to_string(),
|
||||
hashrate_1m: 0.0,
|
||||
hashrate_10m: 0.0,
|
||||
hashrate_1h: 0.0,
|
||||
|
@ -555,9 +558,17 @@ impl PubXmrigProxyApi {
|
|||
}
|
||||
fn update_from_priv(public: &Arc<Mutex<Self>>, private: PrivXmrigProxyApi) {
|
||||
let mut public = public.lock().unwrap();
|
||||
let mut total_hashrate = private
|
||||
.hashrate
|
||||
.total
|
||||
.iter()
|
||||
.map(|x| Some(*x as u64))
|
||||
.collect::<Vec<Option<u64>>>();
|
||||
total_hashrate.remove(5);
|
||||
*public = Self {
|
||||
accepted: private.results.accepted,
|
||||
rejected: private.results.rejected,
|
||||
hashrate: HumanNumber::from_hashrate(&total_hashrate).to_string(),
|
||||
hashrate_1m: private.hashrate.total[0],
|
||||
hashrate_10m: private.hashrate.total[1],
|
||||
hashrate_1h: private.hashrate.total[2],
|
||||
|
|
|
@ -26,6 +26,8 @@ pub const ZERO_SECONDS: std::time::Duration = std::time::Duration::from_secs(0);
|
|||
// Code taken from [https://docs.rs/humantime/] and edited to remove sub-second time, change spacing and some words.
|
||||
use std::time::Duration;
|
||||
|
||||
use readable::num::Float;
|
||||
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
pub struct HumanTime(Duration);
|
||||
|
||||
|
@ -51,34 +53,29 @@ impl HumanTime {
|
|||
HumanTime(Duration::from_secs(u))
|
||||
}
|
||||
|
||||
fn plural(
|
||||
f: &mut std::fmt::Formatter,
|
||||
started: &mut bool,
|
||||
name: &str,
|
||||
value: u64,
|
||||
) -> std::fmt::Result {
|
||||
fn plural(started: &mut bool, name: &str, value: u64, separator: &str) -> String {
|
||||
// do not show time if value is 0 unless it is for seconds.
|
||||
let mut string = String::new();
|
||||
if value > 0 {
|
||||
if *started {
|
||||
f.write_str("\n")?;
|
||||
string.push_str(separator);
|
||||
}
|
||||
write!(f, "{} {}", value, name)?;
|
||||
string.push_str(&value.to_string());
|
||||
string.push(' ');
|
||||
string.push_str(name);
|
||||
if value > 1 {
|
||||
f.write_str("s")?;
|
||||
string.push('s');
|
||||
}
|
||||
*started = true;
|
||||
}
|
||||
Ok(())
|
||||
string
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for HumanTime {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
pub fn display(&self, wrap: bool) -> String {
|
||||
let secs = self.0.as_secs();
|
||||
if secs == 0 {
|
||||
f.write_str("0 seconds")?;
|
||||
return Ok(());
|
||||
return String::from("0 second");
|
||||
}
|
||||
|
||||
let separator = if wrap { "\n" } else { ", " };
|
||||
let years = secs / 31_557_600; // 365.25d
|
||||
let ydays = secs % 31_557_600;
|
||||
let months = ydays / 2_630_016; // 30.44d
|
||||
|
@ -86,17 +83,20 @@ impl std::fmt::Display for HumanTime {
|
|||
let days = mdays / 86400;
|
||||
let day_secs = mdays % 86400;
|
||||
let hours = day_secs / 3600;
|
||||
dbg!(&day_secs);
|
||||
let minutes = day_secs % 3600 / 60;
|
||||
dbg!(&minutes);
|
||||
let seconds = day_secs % 60;
|
||||
|
||||
let started = &mut false;
|
||||
Self::plural(f, started, "year", years)?;
|
||||
Self::plural(f, started, "month", months)?;
|
||||
Self::plural(f, started, "day", days)?;
|
||||
Self::plural(f, started, "hour", hours)?;
|
||||
Self::plural(f, started, "minute", minutes)?;
|
||||
Self::plural(f, started, "second", seconds)?;
|
||||
Ok(())
|
||||
dbg!(&seconds);
|
||||
let mut started = false;
|
||||
let mut string = String::new();
|
||||
string.push_str(&Self::plural(&mut started, "year", years, separator));
|
||||
string.push_str(&Self::plural(&mut started, "month", months, separator));
|
||||
string.push_str(&Self::plural(&mut started, "day", days, separator));
|
||||
string.push_str(&Self::plural(&mut started, "hour", hours, separator));
|
||||
string.push_str(&Self::plural(&mut started, "minute", minutes, separator));
|
||||
string.push_str(&Self::plural(&mut started, "second", seconds, separator));
|
||||
string
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -184,26 +184,36 @@ impl HumanNumber {
|
|||
Self(buf.as_str().to_string())
|
||||
}
|
||||
#[inline]
|
||||
pub fn from_hashrate(array: [Option<f32>; 3]) -> Self {
|
||||
let mut string = "[".to_string();
|
||||
let mut buf = num_format::Buffer::new();
|
||||
pub fn from_hashrate(array: &[Option<u64>]) -> Self {
|
||||
let mut string = String::new();
|
||||
// let mut buf = num_format::Buffer::new();
|
||||
|
||||
let mut n = 0;
|
||||
let mut n = 1;
|
||||
for i in array {
|
||||
match i {
|
||||
Some(f) => {
|
||||
let f = f as u128;
|
||||
buf.write_formatted(&f, &LOCALE);
|
||||
string.push_str(buf.as_str());
|
||||
string.push_str(" H/s");
|
||||
if *f == 0 {
|
||||
string.push_str("[??? H/s]");
|
||||
} else {
|
||||
let f = *f as f64;
|
||||
let (value, metric) = match f {
|
||||
x if x >= 1000.0 => (Float::from_3(f / 1000.0), " K"),
|
||||
x if x >= 1000000.0 => (Float::from_3(f / (1000.0 * 1000.0)), " M"),
|
||||
_ => (Float::from_0(f), " "),
|
||||
};
|
||||
string.push('[');
|
||||
// buf.write_formatted(&value, &LOCALE);
|
||||
string.push_str(value.as_str());
|
||||
string.push_str(metric);
|
||||
string.push_str("H/s]");
|
||||
}
|
||||
}
|
||||
None => string.push_str("??? H/s"),
|
||||
None => string.push_str("[??? H/s]"),
|
||||
}
|
||||
if n != 2 {
|
||||
string.push_str(", ");
|
||||
if n != array.len() {
|
||||
string.push('\n');
|
||||
n += 1;
|
||||
} else {
|
||||
string.push(']');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -263,13 +273,14 @@ mod test {
|
|||
assert!(HumanNumber::to_percent(0.001).to_string() == "0%");
|
||||
assert!(HumanNumber::to_percent(12.123_123).to_string() == "12.12%");
|
||||
assert!(HumanNumber::to_percent_3_point(0.001).to_string() == "0.001%");
|
||||
dbg!(HumanNumber::from_hashrate(&[Some(123), Some(11111), None]).to_string());
|
||||
assert!(
|
||||
HumanNumber::from_hashrate([Some(123.1), Some(11111.1), None]).to_string()
|
||||
== "[123 H/s, 11,111 H/s, ??? H/s]"
|
||||
HumanNumber::from_hashrate(&[Some(123), Some(11111), None]).to_string()
|
||||
== "[123 H/s]\n[11.111 KH/s]\n[??? H/s]"
|
||||
);
|
||||
assert!(
|
||||
HumanNumber::from_hashrate([None, Some(1.123), Some(123_123.31)]).to_string()
|
||||
== "[??? H/s, 1 H/s, 123,123 H/s]"
|
||||
HumanNumber::from_hashrate(&[None, Some(1), Some(123_123)]).to_string()
|
||||
== "[??? H/s]\n[1 H/s]\n[123.123 KH/s]"
|
||||
);
|
||||
assert!(
|
||||
HumanNumber::from_load([Some(123.1234), Some(321.321), None]).to_string()
|
||||
|
@ -327,69 +338,83 @@ mod test {
|
|||
fn human_time() {
|
||||
use crate::human::HumanTime;
|
||||
use std::time::Duration;
|
||||
assert!(HumanTime::into_human(Duration::from_secs(0)).to_string() == "0 seconds");
|
||||
assert!(HumanTime::into_human(Duration::from_secs(1)).to_string() == "1 second");
|
||||
assert!(HumanTime::into_human(Duration::from_secs(2)).to_string() == "2 seconds");
|
||||
assert!(HumanTime::into_human(Duration::from_secs(59)).to_string() == "59 seconds");
|
||||
assert!(HumanTime::into_human(Duration::from_secs(60)).to_string() == "1 minute");
|
||||
assert!(HumanTime::into_human(Duration::from_secs(61)).to_string() == "1 minute\n1 second");
|
||||
assert!(HumanTime::into_human(Duration::from_secs(0)).display(true) == "0 second");
|
||||
assert!(HumanTime::into_human(Duration::from_secs(1)).display(true) == "1 second");
|
||||
assert!(HumanTime::into_human(Duration::from_secs(2)).display(true) == "2 seconds");
|
||||
assert!(HumanTime::into_human(Duration::from_secs(59)).display(true) == "59 seconds");
|
||||
dbg!(HumanTime::into_human(Duration::from_secs(60)).display(true));
|
||||
assert!(HumanTime::into_human(Duration::from_secs(60)).display(true) == "1 minute");
|
||||
assert!(
|
||||
HumanTime::into_human(Duration::from_secs(62)).to_string() == "1 minute\n2 seconds"
|
||||
);
|
||||
assert!(HumanTime::into_human(Duration::from_secs(120)).to_string() == "2 minutes");
|
||||
assert!(
|
||||
HumanTime::into_human(Duration::from_secs(121)).to_string() == "2 minutes\n1 second"
|
||||
HumanTime::into_human(Duration::from_secs(61)).display(true) == "1 minute\n1 second"
|
||||
);
|
||||
assert!(
|
||||
HumanTime::into_human(Duration::from_secs(122)).to_string() == "2 minutes\n2 seconds"
|
||||
HumanTime::into_human(Duration::from_secs(62)).display(true) == "1 minute\n2 seconds"
|
||||
);
|
||||
assert!(HumanTime::into_human(Duration::from_secs(120)).display(true) == "2 minutes");
|
||||
assert!(
|
||||
HumanTime::into_human(Duration::from_secs(121)).display(true) == "2 minutes\n1 second"
|
||||
);
|
||||
assert!(
|
||||
HumanTime::into_human(Duration::from_secs(179)).to_string() == "2 minutes\n59 seconds"
|
||||
HumanTime::into_human(Duration::from_secs(122)).display(true) == "2 minutes\n2 seconds"
|
||||
);
|
||||
assert!(
|
||||
HumanTime::into_human(Duration::from_secs(3599)).to_string()
|
||||
HumanTime::into_human(Duration::from_secs(179)).display(true)
|
||||
== "2 minutes\n59 seconds"
|
||||
);
|
||||
assert!(
|
||||
HumanTime::into_human(Duration::from_secs(3599)).display(true)
|
||||
== "59 minutes\n59 seconds"
|
||||
);
|
||||
assert!(HumanTime::into_human(Duration::from_secs(3600)).to_string() == "1 hour");
|
||||
assert!(HumanTime::into_human(Duration::from_secs(3601)).to_string() == "1 hour\n1 second");
|
||||
assert!(HumanTime::into_human(Duration::from_secs(3600)).display(true) == "1 hour");
|
||||
assert!(
|
||||
HumanTime::into_human(Duration::from_secs(3602)).to_string() == "1 hour\n2 seconds"
|
||||
);
|
||||
assert!(HumanTime::into_human(Duration::from_secs(3660)).to_string() == "1 hour\n1 minute");
|
||||
assert!(
|
||||
HumanTime::into_human(Duration::from_secs(3720)).to_string() == "1 hour\n2 minutes"
|
||||
HumanTime::into_human(Duration::from_secs(3601)).display(true) == "1 hour\n1 second"
|
||||
);
|
||||
assert!(
|
||||
HumanTime::into_human(Duration::from_secs(86399)).to_string()
|
||||
HumanTime::into_human(Duration::from_secs(3602)).display(true) == "1 hour\n2 seconds"
|
||||
);
|
||||
assert!(
|
||||
HumanTime::into_human(Duration::from_secs(3660)).display(true) == "1 hour\n1 minute"
|
||||
);
|
||||
assert!(
|
||||
HumanTime::into_human(Duration::from_secs(3720)).display(true) == "1 hour\n2 minutes"
|
||||
);
|
||||
assert!(
|
||||
HumanTime::into_human(Duration::from_secs(86399)).display(true)
|
||||
== "23 hours\n59 minutes\n59 seconds"
|
||||
);
|
||||
assert!(HumanTime::into_human(Duration::from_secs(86400)).to_string() == "1 day");
|
||||
assert!(HumanTime::into_human(Duration::from_secs(86401)).to_string() == "1 day\n1 second");
|
||||
assert!(HumanTime::into_human(Duration::from_secs(86400)).display(true) == "1 day");
|
||||
assert!(
|
||||
HumanTime::into_human(Duration::from_secs(86402)).to_string() == "1 day\n2 seconds"
|
||||
HumanTime::into_human(Duration::from_secs(86401)).display(true) == "1 day\n1 second"
|
||||
);
|
||||
assert!(HumanTime::into_human(Duration::from_secs(86460)).to_string() == "1 day\n1 minute");
|
||||
assert!(
|
||||
HumanTime::into_human(Duration::from_secs(86520)).to_string() == "1 day\n2 minutes"
|
||||
HumanTime::into_human(Duration::from_secs(86402)).display(true) == "1 day\n2 seconds"
|
||||
);
|
||||
assert!(HumanTime::into_human(Duration::from_secs(90000)).to_string() == "1 day\n1 hour");
|
||||
assert!(HumanTime::into_human(Duration::from_secs(93600)).to_string() == "1 day\n2 hours");
|
||||
assert!(
|
||||
HumanTime::into_human(Duration::from_secs(604799)).to_string()
|
||||
HumanTime::into_human(Duration::from_secs(86460)).display(true) == "1 day\n1 minute"
|
||||
);
|
||||
assert!(
|
||||
HumanTime::into_human(Duration::from_secs(86520)).display(true) == "1 day\n2 minutes"
|
||||
);
|
||||
assert!(HumanTime::into_human(Duration::from_secs(90000)).display(true) == "1 day\n1 hour");
|
||||
assert!(
|
||||
HumanTime::into_human(Duration::from_secs(93600)).display(true) == "1 day\n2 hours"
|
||||
);
|
||||
assert!(
|
||||
HumanTime::into_human(Duration::from_secs(604799)).display(true)
|
||||
== "6 days\n23 hours\n59 minutes\n59 seconds"
|
||||
);
|
||||
assert!(HumanTime::into_human(Duration::from_secs(604800)).to_string() == "7 days");
|
||||
assert!(HumanTime::into_human(Duration::from_secs(2630016)).to_string() == "1 month");
|
||||
assert!(HumanTime::into_human(Duration::from_secs(604800)).display(true) == "7 days");
|
||||
assert!(HumanTime::into_human(Duration::from_secs(2630016)).display(true) == "1 month");
|
||||
assert!(
|
||||
HumanTime::into_human(Duration::from_secs(3234815)).to_string()
|
||||
HumanTime::into_human(Duration::from_secs(3234815)).display(true)
|
||||
== "1 month\n6 days\n23 hours\n59 minutes\n59 seconds"
|
||||
);
|
||||
assert!(HumanTime::into_human(Duration::from_secs(5260032)).to_string() == "2 months");
|
||||
assert!(HumanTime::into_human(Duration::from_secs(31557600)).to_string() == "1 year");
|
||||
assert!(HumanTime::into_human(Duration::from_secs(63115200)).to_string() == "2 years");
|
||||
assert!(HumanTime::into_human(Duration::from_secs(5260032)).display(true) == "2 months");
|
||||
assert!(HumanTime::into_human(Duration::from_secs(31557600)).display(true) == "1 year");
|
||||
assert!(HumanTime::into_human(Duration::from_secs(63115200)).display(true) == "2 years");
|
||||
assert_eq!(
|
||||
HumanTime::into_human(Duration::from_secs(18446744073709551615)).to_string(),
|
||||
"584542046090 years\n7 months\n15 days\n17 hours\n5 minutes\n3 seconds",
|
||||
HumanTime::into_human(Duration::from_secs(18446744073709551615)).display(true),
|
||||
"584542046090 years\n7 months\n15 days\n17 hours\n5 minutes\n3 seconds"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue