Skip to main content

use_probability/
error.rs

1use core::fmt;
2use std::error::Error;
3
4/// Errors returned by validated probability helpers.
5#[derive(Debug, Clone, Copy, PartialEq)]
6pub enum ProbabilityError {
7    /// A probability value must be finite.
8    NonFiniteProbability(f64),
9    /// A probability value must stay in the closed interval `[0, 1]`.
10    ProbabilityOutOfRange(f64),
11    /// A ratio denominator must be greater than zero.
12    ZeroTotal,
13    /// A ratio numerator must not exceed the denominator.
14    PartExceedsTotal {
15        /// The numerator.
16        part: u64,
17        /// The denominator.
18        total: u64,
19    },
20}
21
22impl ProbabilityError {
23    #[allow(clippy::manual_range_contains)]
24    pub(crate) const fn validate_probability(value: f64) -> Result<f64, Self> {
25        if !value.is_finite() {
26            return Err(Self::NonFiniteProbability(value));
27        }
28
29        if value < 0.0 || value > 1.0 {
30            return Err(Self::ProbabilityOutOfRange(value));
31        }
32
33        Ok(value)
34    }
35
36    pub(crate) const fn validate_fraction(part: u64, total: u64) -> Result<(), Self> {
37        if total == 0 {
38            return Err(Self::ZeroTotal);
39        }
40
41        if part > total {
42            return Err(Self::PartExceedsTotal { part, total });
43        }
44
45        Ok(())
46    }
47}
48
49impl fmt::Display for ProbabilityError {
50    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
51        match self {
52            Self::NonFiniteProbability(value) => {
53                write!(formatter, "probability must be finite, got {value}")
54            },
55            Self::ProbabilityOutOfRange(value) => {
56                write!(formatter, "probability must be in [0, 1], got {value}")
57            },
58            Self::ZeroTotal => write!(formatter, "total count must be greater than zero"),
59            Self::PartExceedsTotal { part, total } => {
60                write!(
61                    formatter,
62                    "part must be less than or equal to total, got part={part}, total={total}"
63                )
64            },
65        }
66    }
67}
68
69impl Error for ProbabilityError {}