diff --git a/src/handlers/download.rs b/src/handlers/download.rs index e9207a7..98fda14 100644 --- a/src/handlers/download.rs +++ b/src/handlers/download.rs @@ -11,7 +11,7 @@ use crate::{ nix_path, pad_string, }; -static DOWNLOAD_CHAR: LazyLock = LazyLock::new(|| "#".blue().bold().to_string()); +static DOWNLOAD_CHAR: LazyLock = LazyLock::new(|| "-".blue().bold().to_string()); static DONE_CHAR: LazyLock = LazyLock::new(|| "#".green().bold().to_string()); const INFO_WIDTH: usize = 13; @@ -29,7 +29,6 @@ impl Handler for SubstituteHandler { id, .. } => { - state.println(format!("Substituting {} -> {}", source, target))?; state.plug(CopyHandler(*id)); // Handle global start action Ok(true) @@ -58,10 +57,6 @@ impl Handler for CopyHandler { parent, .. } if parent == &self.0 => { - state.println(format!( - "Copying {} <- {} (from {})", - destination, path, origin - ))?; let bar = state.add_pb(ProgressBar::new(1)); state.plug(DownloadHandler::new( state.term_width, @@ -228,9 +223,7 @@ impl Handler for DownloadHandler { parent, .. } if parent == &self.copy_id => { - state.println(format!("Downloading {}", target))?; self.id = *id; - // Handle global start action Ok(true) } Action::Result { diff --git a/src/handlers/mod.rs b/src/handlers/mod.rs index 2869ccf..6c35556 100644 --- a/src/handlers/mod.rs +++ b/src/handlers/mod.rs @@ -3,6 +3,7 @@ use crate::action::Action; pub mod download; pub mod fetch; pub mod global; +pub mod substitute_status; pub trait Handler { fn handle( diff --git a/src/handlers/substitute_status.rs b/src/handlers/substitute_status.rs new file mode 100644 index 0000000..70524c7 --- /dev/null +++ b/src/handlers/substitute_status.rs @@ -0,0 +1,161 @@ +use std::{collections::HashMap, sync::LazyLock, time::Instant}; + +use indicatif::{HumanBytes, ProgressBar}; +use owo_colors::OwoColorize; + +use crate::{ + action::{Action, ActionType, BuildStepId, ResultFields, StartFields}, + estimator::Estimator, + handlers::{Handler, fetch::FetchHandler}, + multibar::{BarSegment, MultiBar}, + nix_path, pad_string, +}; + +static DOWNLOAD_CHAR: LazyLock = LazyLock::new(|| "-".blue().bold().to_string()); +static DONE_CHAR: LazyLock = LazyLock::new(|| "#".green().bold().to_string()); +const INFO_WIDTH: usize = 13; + +pub struct CopyPathsHandler; + +impl Handler for CopyPathsHandler { + fn handle( + &mut self, + state: &mut crate::state::State, + action: &crate::action::Action, + ) -> color_eyre::Result { + match action { + Action::Start { + start_type: StartFields::CopyPaths, + id, + .. + } => { + state.println(format!("CopyPaths start"))?; + let progress = state.add_pb(ProgressBar::new(1)); + state.plug(SubstitutionStatusHandler::new( + id, + state.term_width, + progress, + )); + // Handle global start action + Ok(true) + } + _ => Ok(true), + } + } +} + +pub struct SubstitutionStatusHandler { + id: BuildStepId, + progress: ProgressBar, + state_copy: HashMap, + state_transfer: HashMap, + state_self: [u64; 2], + max_copy: u64, + max_transfer: u64, +} + +impl SubstitutionStatusHandler { + fn new(id: &BuildStepId, width: u16, progress: ProgressBar) -> Self { + let mut new = Self { + id: *id, + progress, + state_copy: HashMap::new(), + state_transfer: HashMap::new(), + state_self: [0, 0], + max_copy: 0, + max_transfer: 0, + }; + new.draw_bar(width); + new + } + + fn get_done(&self) -> u64 { + self.state_transfer.values().map(|&[done, ..]| done).sum() + } + + fn get_running(&self) -> u64 { + self.state_transfer + .values() + .map(|&[_, expected, ..]| expected) + .sum() + } + + fn get_unpacked(&self) -> u64 { + self.state_copy.values().map(|&[done, ..]| done).sum() + } + + fn draw_bar(&mut self, width: u16) {} +} + +impl Handler for SubstitutionStatusHandler { + fn handle( + &mut self, + state: &mut crate::state::State, + action: &crate::action::Action, + ) -> color_eyre::Result { + match action { + Action::Start { + start_type: StartFields::CopyPath { path, .. }, + id, + .. + } => { + self.state_copy.insert(*id, [0; 2]); + Ok(true) + } + Action::Start { + start_type: StartFields::FileTransfer { .. }, + id, + .. + } => { + self.state_transfer.insert(*id, [0; 2]); + Ok(true) + } + + Action::Result { + id, + fields: + ResultFields::SetExpected { + action: ActionType::CopyPaths, + expected, + }, + } => { + self.max_copy = *expected; + self.draw_bar(state.term_width); + Ok(true) + } + Action::Result { + id, + fields: + ResultFields::SetExpected { + action: ActionType::CopyPaths, + expected, + }, + } => { + self.max_copy = *expected; + self.draw_bar(state.term_width); + Ok(true) + } + + Action::Result { + id, + fields: ResultFields::Progress { done, expected, .. }, + } => { + if id == &self.id { + self.state_self = [*done, *expected]; + self.draw_bar(state.term_width); + } + if let Some(copy) = self.state_copy.get_mut(id) { + *copy = [*done, *expected]; + self.draw_bar(state.term_width); + } + + if let Some(transfer) = self.state_transfer.get_mut(id) { + *transfer = [*done, *expected]; + self.draw_bar(state.term_width); + } + Ok(true) + } + _ => Ok(true), + } + } +} diff --git a/src/state.rs b/src/state.rs index cb55cab..3f97d08 100644 --- a/src/state.rs +++ b/src/state.rs @@ -3,7 +3,10 @@ use std::{io, marker::PhantomData, rc::Rc}; use console::style; use indicatif::{MultiProgress, ProgressBar, ProgressFinish, ProgressStyle}; -use crate::handlers::{Handler, download::SubstituteHandler, global::GlobalHandler}; +use crate::handlers::{ + Handler, download::SubstituteHandler, global::GlobalHandler, + substitute_status::CopyPathsHandler, +}; pub struct State { pub multi_progress: Rc, @@ -21,6 +24,7 @@ impl State { separator: None, }; state.plug(GlobalHandler); + state.plug(CopyPathsHandler); state.plug(SubstituteHandler); state