From df5353da8f3a87c522c822b8a4cf0228af6900d9 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Sun, 15 May 2022 21:21:28 +0100 Subject: [PATCH] progress: Allow ProgressInfo's Count to contain only a proportion We're going to introduce a thing that will use this. Signed-off-by: Ian Jackson --- Cargo.lock | 2 +- Cargo.toml | 1 - src/crates.rs | 1 - src/imports.rs | 1 - support/Cargo.toml | 1 + support/crates.rs | 1 + support/imports.rs | 1 + support/progress.rs | 54 +++++++++++++++++++++++++++++++---------- support/termprogress.rs | 34 +++++++++++++++++--------- 9 files changed, 67 insertions(+), 29 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1adc166b..b1cb7915 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2683,7 +2683,6 @@ dependencies = [ "crossbeam-utils", "delegate", "downcast-rs", - "educe", "either", "enum-map", "enum_dispatch", @@ -2820,6 +2819,7 @@ dependencies = [ "console", "derive-into-owned", "digest 0.10.3", + "educe", "fehler", "flexi_logger", "fs2", diff --git a/Cargo.toml b/Cargo.toml index fc7fa67b..4471bd25 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,7 +39,6 @@ cast_trait_object="0.1" crossbeam-utils="0.8" delegate="0.6" downcast-rs="1" -educe="0.4" either="1" enum_dispatch="0.3.5" env_logger="0.9" diff --git a/src/crates.rs b/src/crates.rs index 00f0b7ce..8d5b6e24 100644 --- a/src/crates.rs +++ b/src/crates.rs @@ -11,7 +11,6 @@ pub use base64; pub use boolinator; pub use cast_trait_object; pub use delegate; -pub use educe; pub use either; pub use env_logger; pub use glob; diff --git a/src/imports.rs b/src/imports.rs index a948fb83..7c8f9d5b 100644 --- a/src/imports.rs +++ b/src/imports.rs @@ -35,7 +35,6 @@ pub use cast_trait_object::{dyn_upcast, DynCastExt}; pub use const_default::ConstDefault; pub use delegate::delegate; pub use downcast_rs::{impl_downcast, Downcast}; -pub use educe::Educe; pub use either::{Either, Left, Right}; pub use enum_dispatch::enum_dispatch; pub use enum_map::{Enum, EnumMap}; diff --git a/support/Cargo.toml b/support/Cargo.toml index 8fe39eab..ae1b0fa5 100644 --- a/support/Cargo.toml +++ b/support/Cargo.toml @@ -33,6 +33,7 @@ chrono-tz="0.6" console="0.15" derive-into-owned="0.2" digest="0.10" +educe="0.4" fehler="1" fs2="0.4" lazy_static="1" diff --git a/support/crates.rs b/support/crates.rs index 1e077882..17080c75 100644 --- a/support/crates.rs +++ b/support/crates.rs @@ -10,6 +10,7 @@ pub use anyhow; pub use chrono; pub use chrono_tz; pub use digest; +pub use educe; pub use flexi_logger; pub use fs2; pub use lazy_static; diff --git a/support/imports.rs b/support/imports.rs index 4b2b7968..2202a7ab 100644 --- a/support/imports.rs +++ b/support/imports.rs @@ -75,6 +75,7 @@ pub use crate::authproofs::AuthorisationSuperuser; pub use crate::childio; pub use crate::config::*; pub use crate::debugmutex::DebugIdentify; +pub use educe::Educe; pub use crate::digestrw::{self, *}; pub use crate::fake_rng::*; pub use crate::fake_time::*; diff --git a/support/progress.rs b/support/progress.rs index d71c82bd..163eafa5 100644 --- a/support/progress.rs +++ b/support/progress.rs @@ -12,11 +12,33 @@ pub struct ProgressInfo<'pi> { #[derive(Debug,Clone,Serialize,Deserialize,IntoOwned)] pub struct Count<'pi> { - pub i: usize, - pub n: usize, + pub value: Value, pub desc: Cow<'pi, str>, } +#[derive(Debug,Clone,Serialize,Deserialize,IntoOwned)] +#[derive(Educe)] +#[educe(Default)] +pub enum Value { + #[educe(Default)] Exact { + i: usize, + n: usize, + }, + Fraction { + f: f32, // [0..1] + } +} + +impl Value { + pub fn fraction(&self) -> f32 { + match self { + &Value::Exact{ i:_, n } if n == 0 => 0., + &Value::Exact{ i, n } => (i as f32) / (n as f32), + &Value::Fraction{ f } => f, + } + } +} + pub trait Originator { fn report(&mut self, info: ProgressInfo<'_>); fn phase_begin_(&mut self, phase: Count<'_>, len: usize); @@ -31,12 +53,14 @@ pub struct ResponseOriginator<'c,'w,W,F> where W: Write { } impl<'c,'w,W,F> ResponseOriginator<'c,'w,W,F> where W: Write { pub fn new(chan: &'c mut ResponseWriter<'w,W>, - formatter: F) -> Self { Self { - chan, - phase: Count { i:0, n:0, desc: Cow::Borrowed("") }, - len: 0, - formatter, - } } + formatter: F) -> Self { + Self { + chan, + phase: Count { value: default(), desc: Cow::Borrowed("") }, + len: 0, + formatter, + } + } } impl Originator for ResponseOriginator<'_,'_,W,F> @@ -53,9 +77,10 @@ where W: Write, self.len = len; } fn item_(&mut self, item: usize, desc: Cow<'_, str>) { + let value = Value::Exact { i: item, n: self.len }; self.report(ProgressInfo { phase: self.phase.clone(), - item: Count { i: item, n: self.len, desc } + item: Count { value, desc } }) } } @@ -70,9 +95,12 @@ impl Originator for () { pub trait Enum: EnumCount + ToPrimitive + EnumMessage { } impl From for Count<'static> where T: Enum { fn from(t: T) -> Count<'static> { - Count { + let value = Value::Exact { i: t.to_usize().unwrap(), n: T::COUNT - 1, + }; + Count { + value, // Show be Borrowed https://github.com/Peternator7/strum/issues/159 desc: Cow::Owned(t.get_message().unwrap_or("...").to_owned()), } @@ -80,16 +108,16 @@ impl From for Count<'static> where T: Enum { } impl<'t> From<&'t str> for Count<'t> { fn from(s: &'t str) -> Count<'t> { - Count { i:0, n:0, desc: Cow::Borrowed(s) } + Count { value: default(), desc: Cow::Borrowed(s) } } } impl From for Count<'static> { fn from(s: String) -> Count<'static> { - Count { i:0, n:0, desc: Cow::Owned(s) } + Count { value: default(), desc: Cow::Owned(s) } } } impl<'t> From<()> for Count<'t> { fn from(_:()) -> Count<'t> { - Count { i:0, n:0, desc: Cow::Borrowed("") } + Count { value: default(), desc: Cow::Borrowed("") } } } #[ext(pub, name=OriginatorExt)] diff --git a/support/termprogress.rs b/support/termprogress.rs index d56c01f9..7864d24d 100644 --- a/support/termprogress.rs +++ b/support/termprogress.rs @@ -120,12 +120,10 @@ impl TermReporter { fn bar(&self, out: &mut String, fwidth: Col, info: &progress::Count) { let desc = console::strip_ansi_codes(&info.desc); - let w_change = if info.n == 0 { 0 } else { - min( - ((info.i as f32) / (info.n as f32) * (fwidth as f32)) as Col, - fwidth // just in case - ) - }; + let w_change = min( + (info.value.fraction() * (fwidth as f32)) as Col, + fwidth // just in case + ); let mut desc = desc .chars() .chain(iter::repeat(' ')) @@ -166,7 +164,7 @@ impl Drop for TermReporter { pub struct Nest { outer_n: usize, outer_i: usize, - inner_last_phase: usize, + inner_last_frac: f32, actual_reporter: Box, } @@ -177,17 +175,20 @@ impl Nest { actual_reporter, outer_n: outer_count, outer_i: 0, - inner_last_phase: 0, + inner_last_frac: 0., } } } impl Reporter for Nest { fn report(&mut self, inner_pi: &ProgressInfo<'_>) { + use progress::Value; + // Autodetect new outer phase item, when inner pahse rewinds - if inner_pi.phase.i < self.inner_last_phase { + let inner_frac = inner_pi.phase.value.fraction(); + if inner_frac < self.inner_last_frac { self.outer_i += 1; } - self.inner_last_phase = inner_pi.phase.i; + self.inner_last_frac = inner_frac; let desc = if self.outer_n > 1 { format!("{}/{} {}", self.outer_i, self.outer_n, @@ -196,10 +197,19 @@ impl Reporter for Nest { inner_pi.phase.desc.clone() }; + let outer_value = match inner_pi.phase.value { + Value::Exact { i, n } => Value::Exact { + i: i + n * self.outer_i, + n: n * self.outer_n, + }, + Value::Fraction { f } => Value::Fraction { + f: f * (1.0 / self.outer_n as f32) + + Value::Exact { i: self.outer_i, n: self.outer_n }.fraction(), + }, + }; let outer_phase = progress::Count { - i: inner_pi.phase.i + inner_pi.phase.n * self.outer_i, - n: inner_pi.phase.n * self.outer_n, desc, + value: outer_value, }; let outer_pi = ProgressInfo { -- 2.30.2