use std::io::Write;
use std::time::Duration;
use owo_colors::Style;
use crate::bar::Bar;
use crate::layout::{Layout, RenderContext};
use crate::progressive::Progressive;
use crate::term::{self, clear_line};
use crate::Theme;
pub(crate) struct FrameContext {
pub spinner_char: Option<char>,
pub elapsed: Duration,
pub show_elapsed: bool,
pub spinner_style: Style,
pub annotation_style: Style,
}
pub(crate) struct Line<'a> {
bar: Bar<'a>,
bar_width: usize,
layout: Layout,
render_buf: String,
}
impl<'a> Line<'a> {
pub(crate) fn new(theme: &Theme<'a>) -> Self {
Self {
bar: theme.bar.clone(),
bar_width: theme.effective_bar_width(),
layout: theme.layout.clone(),
render_buf: String::new(),
}
}
pub(crate) fn render_into<'b, P: Progressive<'b> + ?Sized>(
&mut self,
item: &P,
frame: &FrameContext,
) -> &str {
let ctx = RenderContext {
spinner: frame.spinner_char,
elapsed: frame.elapsed,
show_elapsed: frame.show_elapsed,
bar: &self.bar,
bar_width: self.bar_width,
progress: item.progress(),
bytes_done: item.bytes_done(),
bytes_total: item.bytes_total(),
rate: item.rate(),
label: item.label(),
message: item.message(),
spinner_style: frame.spinner_style,
annotation_style: frame.annotation_style,
};
self.render_buf.clear();
self.layout.render(&ctx, &mut self.render_buf);
&self.render_buf
}
pub(crate) fn standalone_render<'b, P: Progressive<'b> + ?Sized>(
&mut self,
item: &P,
frame: &FrameContext,
is_tty: bool,
) {
if !is_tty {
return;
}
let _ = self.render_into(item, frame);
let mut stdout = std::io::stdout().lock();
let _ = stdout.write_all(term::HIDE_CURSOR);
let _ = clear_line(&mut stdout);
let _ = stdout.write_all(self.render_buf.as_bytes());
let _ = stdout.flush();
}
pub(crate) fn standalone_clear(is_tty: bool) {
if !is_tty {
return;
}
let mut stdout = std::io::stdout().lock();
let _ = clear_line(&mut stdout);
let _ = stdout.flush();
}
}