use odl::progress::{Phase, ProgressEvent, ProgressReporter};
use serde_json::json;
pub fn phase_str(phase: Phase) -> &'static str {
match phase {
Phase::Evaluating => "evaluating",
Phase::ResolvingConflicts => "resolving_conflicts",
Phase::Downloading => "downloading",
Phase::Assembling => "assembling",
Phase::Flushing => "flushing",
Phase::Verifying => "verifying",
}
}
pub fn emit_line(value: serde_json::Value) {
println!("{value}");
}
pub struct JsonReporter {
url: String,
}
impl JsonReporter {
pub fn new(url: String) -> Self {
Self { url }
}
}
impl ProgressReporter for JsonReporter {
fn on_event(&self, event: ProgressEvent) {
let url = &self.url;
match event {
ProgressEvent::FilenameResolved(name) => {
emit_line(json!({"type": "filename", "url": url, "filename": name}));
}
ProgressEvent::PhaseChanged(phase) => {
emit_line(json!({"type": "phase", "url": url, "phase": phase_str(phase)}));
}
ProgressEvent::Progress { downloaded, total } => {
emit_line(json!({
"type": "progress",
"url": url,
"downloaded": downloaded,
"total": total,
}));
}
ProgressEvent::Message(message) => {
if !message.is_empty() {
emit_line(json!({"type": "message", "url": url, "message": message}));
}
}
ProgressEvent::Completed {
path,
already_complete,
} => {
emit_line(json!({
"type": "completed",
"url": url,
"path": path.to_string_lossy(),
"already_complete": already_complete,
}));
}
ProgressEvent::Cancelled => {
emit_line(json!({"type": "cancelled", "url": url}));
}
ProgressEvent::Failed { message } => {
emit_line(json!({"type": "failed", "url": url, "message": message}));
}
ProgressEvent::Speed { .. }
| ProgressEvent::PartAdded { .. }
| ProgressEvent::PartProgress { .. }
| ProgressEvent::PartFinished { .. }
| ProgressEvent::PartSpeed { .. }
| ProgressEvent::PartRetrying { .. } => {}
}
}
}