rework multibar

This commit is contained in:
2025-11-12 06:10:37 +00:00
parent ac377a9c9c
commit 4dfefb0602
3 changed files with 76 additions and 21 deletions

View File

@@ -7,7 +7,7 @@ use console::{Term, style};
use indicatif::{MultiProgress, ProgressBar, ProgressStyle, TermLike}; use indicatif::{MultiProgress, ProgressBar, ProgressStyle, TermLike};
use crate::action::StartFields; use crate::action::StartFields;
use crate::multibar::MultiBar; use crate::multibar::{BarSegment, MultiBar};
use crate::state_manager::{BuildEnumState, BuildState, State, StateManager}; use crate::state_manager::{BuildEnumState, BuildState, State, StateManager};
static LAZY: LazyLock<i32> = LazyLock::new(|| { static LAZY: LazyLock<i32> = LazyLock::new(|| {
@@ -89,10 +89,10 @@ fn main() -> Result<(), color_eyre::Report> {
let term = Term::stdout(); let term = Term::stdout();
let empty = style("-").blue().to_string(); let empty = style("-").blue().to_string();
let bar = MultiBar([ let bar = MultiBar([
("=", 50, false), BarSegment::Dynamic("=", 10),
(">", 1, true), BarSegment::Static(">"),
(empty.as_str(), 3, false), BarSegment::Dynamic(empty.as_str(), 3),
(" ", 30, false), BarSegment::Dynamic(" ", 50),
]) ])
.scale(u64::from(term.size().1 - 2)); .scale(u64::from(term.size().1 - 2));
println!("[{}]", bar); println!("[{}]", bar);

View File

@@ -1,37 +1,92 @@
use std::fmt; use std::fmt;
#[derive(Debug, Clone, Copy)]
pub enum BarSegment<'s> {
Dynamic(&'s str, u64),
Static(&'s str),
}
impl<'s> BarSegment<'s> {
fn char(&self) -> &'s str {
match self {
BarSegment::Dynamic(c, _) => c,
BarSegment::Static(c) => c,
}
}
fn length(&self) -> u64 {
match self {
BarSegment::Dynamic(c, len) => *len,
BarSegment::Static(c) => c.len() as u64,
}
}
fn is_static(&self) -> bool {
matches!(self, BarSegment::Static(_))
}
fn scaled(&self, new_len: u64) -> Self {
match self {
BarSegment::Dynamic(c, _) => BarSegment::Dynamic(c, new_len),
BarSegment::Static(c) => BarSegment::Static(c),
}
}
}
#[derive(Debug)] #[derive(Debug)]
pub struct MultiBar<'s, const N: usize>(pub [(&'s str, u64, bool); N]); pub struct MultiBar<'s, const N: usize>(pub [BarSegment<'s>; N]);
impl<const N: usize> MultiBar<'_, N> { impl<const N: usize> MultiBar<'_, N> {
/// Total length of the bar fn dynamic_length(&self) -> u64 {
pub(crate) fn length(&self) -> u64 { self.0
self.0.iter().map(|(_, len, _)| *len).sum::<u64>() .iter()
.filter(|seg| !seg.is_static())
.map(|seg| seg.length())
.sum::<u64>()
}
fn static_length(&self) -> u64 {
self.0
.iter()
.filter(|seg| seg.is_static())
.map(|seg| seg.length())
.sum::<u64>()
} }
/// Transforms the bar to be of target size /// Transforms the bar to be of target size
/// Static parts remain the same length, dynamic parts are scaled proportionally
pub(crate) fn scale(&self, size: u64) -> Self { pub(crate) fn scale(&self, size: u64) -> Self {
let length = std::cmp::max(self.length(), 1); let static_len = self.static_length();
let dynamic_len = std::cmp::max(self.dynamic_length(), 1);
let available_size = size.saturating_sub(static_len);
let mut prev_prop = 0; let mut prev_prop = 0;
let mut curr_prop = 0; let mut curr_prop = 0;
let inner = self.0.map(|(c, len, const_len)| { let inner = self.0.map(|seg| match seg {
if const_len { BarSegment::Static(_) => seg,
return (c, len, const_len); BarSegment::Dynamic(c, len) => {
curr_prop += len;
let nb_chars = available_size * curr_prop / dynamic_len
- available_size * prev_prop / dynamic_len;
prev_prop = curr_prop;
BarSegment::Dynamic(c, nb_chars)
} }
curr_prop += len;
let nb_chars = size * curr_prop / length - size * prev_prop / length;
prev_prop = curr_prop;
(c, nb_chars, const_len)
}); });
Self(inner) Self(inner)
} }
} }
impl<const N: usize> fmt::Display for MultiBar<'_, N> { impl<const N: usize> fmt::Display for MultiBar<'_, N> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
for &(c, len, _) in &self.0 { for seg in &self.0 {
let (c, len) = match seg {
BarSegment::Dynamic(c, len) => (c, *len),
BarSegment::Static(c) => (c, c.len() as u64),
};
for _ in 0..len { for _ in 0..len {
f.write_str(c)?; f.write_str(c)?;
} }

View File

@@ -8,6 +8,8 @@ pub struct State<'a> {
pub multi_progress: MultiProgress, pub multi_progress: MultiProgress,
pub manager: StateManager<'a>, pub manager: StateManager<'a>,
pub separator: Option<ProgressBar>, pub separator: Option<ProgressBar>,
pub width: u16,
pub current_width: u16,
} }
impl<'a> State<'a> { impl<'a> State<'a> {
@@ -74,7 +76,6 @@ pub struct BuildState<'a> {
pub path: Option<String>, pub path: Option<String>,
pub progress_bar: Option<ProgressBar>, pub progress_bar: Option<ProgressBar>,
pub state: BuildEnumState<'a>, pub state: BuildEnumState<'a>,
ref_count: usize,
} }
impl<'a> BuildState<'a> { impl<'a> BuildState<'a> {
pub fn new() -> Self { pub fn new() -> Self {
@@ -82,7 +83,6 @@ impl<'a> BuildState<'a> {
path: None, path: None,
progress_bar: None, progress_bar: None,
state: BuildEnumState::Init, state: BuildEnumState::Init,
ref_count: 1,
} }
} }
} }