use core::fmt::Display;
use crate::core::observer::Observe;
use crate::core::state::State;
use crate::core::termination::TerminationReason;
#[derive(Copy, Clone, Debug, Default)]
pub struct Report {
prefix: &'static str,
}
impl Report {
pub fn new() -> Self {
Self { prefix: "" }
}
pub fn with_prefix(prefix: &'static str) -> Self {
Self { prefix }
}
fn line<S>(&self, tag: &str, state: &S)
where
S: State,
S::Float: Display,
{
if self.prefix.is_empty() {
eprintln!(
"[{tag}] iter {} cost {} best {}",
state.iter(),
state.cost(),
state.best_cost(),
);
} else {
eprintln!(
"{} [{tag}] iter {} cost {} best {}",
self.prefix,
state.iter(),
state.cost(),
state.best_cost(),
);
}
}
}
impl<S> Observe<S> for Report
where
S: State,
S::Float: Display,
{
fn observe_init(&mut self, state: &S) {
self.line("init", state);
}
fn observe_iter(&mut self, state: &S) {
self.line("iter", state);
}
fn observe_final(&mut self, state: &S, reason: &TerminationReason) {
self.line("done", state);
if self.prefix.is_empty() {
eprintln!("[done] stopped: {reason:?}");
} else {
eprintln!("{} [done] stopped: {reason:?}", self.prefix);
}
}
}