//! Logging and progress line protocol (pure `std`). //! //! The GUI (Python or future native) consumes plain stdout lines as log text //! and lines prefixed with `PROGRESS_PREFIX` as in-place "replace the last //! line" progress. Keep this byte-compatible with //! `pipeline_360_gui.py`'s expectations. /// Prefix marking a progress (replace-last-line) message. pub const PROGRESS_PREFIX: &str = "[progress] "; /// A sink for emitted messages. `None` means raw stdout. pub type Logger<'a> = Option<&'a dyn Fn(&str)>; /// Emit a normal log line (message-only; the CLI/GUI decides whether to add a newline). pub fn emit(message: &str, logger: Logger) { match logger { Some(f) => f(message), None => println!("{message}"), } } /// Emit a progress (replace-last-line) message with the `[progress] ` prefix. pub fn emit_progress(message: &str, logger: Logger) { if let Some(f) = logger { f(&format!("{PROGRESS_PREFIX}{message}")); } } /// A stage header line, e.g. `==== STAGE 1/4: Extract Sharpest Frames ====`. pub fn stage_header(index: usize, total: usize, title: &str, logger: Logger) { emit("", logger); emit(&format!("==== STAGE {index}/{total}: {title} ===="), logger); }