use std::fmt; #[derive(Debug, Clone, PartialEq)] #[non_exhaustive] pub enum InferenceError { /// Expected and actual lengths of some array-shaped input differ. MismatchedShape { kind: &'static str, expected: usize, got: usize, }, /// An `Outcome` of the wrong variant was supplied for the requested inference. WrongOutcomeKind { context: &'static str, expected: &'static str, got: &'static str, }, /// A probability value is outside `[0, 1]`. InvalidProbability { value: f64 }, /// A scalar parameter is outside its valid range. InvalidParameter { name: &'static str, value: f64 }, /// An event contains tied teams, but the draw probability is zero. /// /// A zero draw probability asserts that draws cannot occur, so a tied /// result has no representable likelihood. Configure a positive `p_draw` /// (via `HistoryBuilder::p_draw` or `GameOptions::p_draw`) to admit ties. TieWithoutDrawProbability { teams: (usize, usize) }, /// Convergence exceeded `max_iter` without falling below `epsilon`. ConvergenceFailed { last_step: (f64, f64), iterations: usize, }, /// Inference produced a non-finite value (NaN or infinity). /// /// Indicates numerical breakdown; the resulting skills are meaningless /// and must not be treated as a converged estimate. NonFiniteResult { context: &'static str, step: (f64, f64), }, /// Negative precision: a Gaussian with `pi < 0` slipped into an API call. NegativePrecision { pi: f64 }, } impl fmt::Display for InferenceError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { Self::MismatchedShape { kind, expected, got, } => { write!(f, "{kind}: expected length {expected}, got {got}") } Self::WrongOutcomeKind { context, expected, got, } => { write!(f, "{context}: expected {expected}, got {got}") } Self::InvalidProbability { value } => { write!(f, "probability must be in [0, 1]; got {value}") } Self::TieWithoutDrawProbability { teams } => { write!( f, "teams {} and {} are tied, but p_draw is 0.0; set a positive draw probability to admit ties", teams.0, teams.1 ) } Self::NonFiniteResult { context, step } => { write!( f, "{context}: inference produced a non-finite result (step = {step:?})" ) } Self::InvalidParameter { name, value } => { write!(f, "{name} is invalid: {value}") } Self::ConvergenceFailed { last_step, iterations, } => { write!( f, "convergence failed after {iterations} iterations; last step = {last_step:?}" ) } Self::NegativePrecision { pi } => { write!(f, "precision must be non-negative; got {pi}") } } } } impl std::error::Error for InferenceError {}