use std::collections::HashMap;
use std::io::IsTerminal;
use std::sync::Arc;
use crate::display::{CliRenderer, DetailLevel};
use crate::event::Event;
use super::live::LiveRenderer;
#[allow(clippy::large_enum_variant)]
pub enum RunRenderer {
Live(LiveRenderer),
Classic(CliRenderer),
}
impl RunRenderer {
pub fn auto(detail: DetailLevel) -> Self {
let is_tty = std::io::stderr().is_terminal();
let no_live = std::env::var("NIKA_NO_LIVE").is_ok();
if is_tty && !no_live && !detail.is_json() && detail != DetailLevel::Min {
Self::Live(LiveRenderer::new(detail))
} else {
Self::Classic(CliRenderer::new(detail))
}
}
pub fn classic(detail: DetailLevel) -> Self {
Self::Classic(CliRenderer::new(detail))
}
pub fn live(detail: DetailLevel) -> Self {
Self::Live(LiveRenderer::new(detail))
}
pub fn init_tasks(&mut self, task_ids: &[String], task_deps: &HashMap<String, Vec<String>>) {
if let Self::Live(ref mut live) = self {
live.init_tasks(task_ids, task_deps);
}
}
pub fn set_task_layers(&mut self, layers: HashMap<Arc<str>, usize>) {
match self {
Self::Live(live) => live.set_task_layers(layers),
Self::Classic(cli) => cli.set_task_layers(layers),
}
}
pub fn last_rendered_id(&self) -> Option<u64> {
match self {
Self::Live(live) => live.last_rendered_id(),
Self::Classic(cli) => cli.last_rendered_id(),
}
}
pub fn render_kind(&mut self, kind: &crate::event::EventKind) {
match self {
Self::Live(live) => live.render_kind(kind),
Self::Classic(cli) => cli.render_kind(kind),
}
}
pub fn render_new_events(&mut self, events: &[Event]) {
match self {
Self::Live(live) => live.render_new_events(events),
Self::Classic(cli) => cli.render_new_events(events),
}
}
pub fn render_summary(&mut self, total_duration_ms: u64, trace_path: Option<&str>) {
match self {
Self::Live(live) => live.render_summary(total_duration_ms, trace_path),
Self::Classic(cli) => cli.render_summary(total_duration_ms, trace_path),
}
}
pub fn render_quiet_summary(&mut self, total_duration_ms: u64) {
match self {
Self::Live(live) => live.render_quiet_summary(total_duration_ms),
Self::Classic(cli) => cli.render_quiet_summary(total_duration_ms),
}
}
pub fn is_live(&self) -> bool {
matches!(self, Self::Live(_))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_classic_mode() {
let renderer = RunRenderer::classic(DetailLevel::Max);
assert!(!renderer.is_live());
assert_eq!(renderer.last_rendered_id(), None);
}
#[test]
fn test_live_mode() {
let renderer = RunRenderer::live(DetailLevel::Max);
assert!(renderer.is_live());
assert_eq!(renderer.last_rendered_id(), None);
}
#[test]
fn test_json_forces_classic() {
let _renderer = RunRenderer::auto(DetailLevel::Json);
}
#[test]
fn test_min_forces_classic() {
let _renderer = RunRenderer::auto(DetailLevel::Min);
}
#[test]
fn test_init_tasks_on_classic_is_noop() {
let mut renderer = RunRenderer::classic(DetailLevel::Max);
let task_ids = vec!["a".to_string(), "b".to_string()];
let deps = HashMap::new();
renderer.init_tasks(&task_ids, &deps); }
}