use crate::model::Model;
use std::fmt;
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[non_exhaustive]
pub enum Warning {
TooFewPoints {
got: usize,
advised: usize,
},
NarrowRange {
decades: f64,
advised: f64,
},
NonMonotonic,
DecreasingCost,
ModelsSkipped(Vec<Model>),
}
impl fmt::Display for Warning {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Warning::TooFewPoints { got, advised } => write!(
f,
"only {got} distinct input sizes measured, {advised} or more advised"
),
Warning::NarrowRange { decades, advised } => write!(
f,
"input sizes span {decades:.1} decades, {advised:.0} or more advised to separate the models"
),
Warning::NonMonotonic => write!(f, "cost rises and falls across the sample"),
Warning::DecreasingCost => write!(f, "cost falls as the input grows"),
Warning::ModelsSkipped(models) => {
write!(f, "models that could not consume the data: ")?;
for (i, model) in models.iter().enumerate() {
match i {
0 => write!(f, "{model}")?,
_ => write!(f, ", {model}")?,
}
}
Ok(())
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn reads_as_a_sentence() {
assert_eq!(
Warning::TooFewPoints { got: 4, advised: 6 }.to_string(),
"only 4 distinct input sizes measured, 6 or more advised"
);
assert_eq!(
Warning::NarrowRange {
decades: 0.4,
advised: 3.0
}
.to_string(),
"input sizes span 0.4 decades, 3 or more advised to separate the models"
);
assert_eq!(
Warning::ModelsSkipped(vec![Model::Logarithmic, Model::Polynomial]).to_string(),
"models that could not consume the data: O(log n), O(n^m)"
);
}
}