1#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
11pub enum ScoringError {
12 #[error("invalid scoring input: {0}")]
13 InvalidInput(String),
14
15 #[error("scoring arithmetic overflow: {0}")]
16 ArithmeticOverflow(String),
17}
18
19pub type ScoringResult<T> = Result<T, ScoringError>;
20
21pub(crate) fn invalid_input(message: impl Into<String>) -> ScoringError {
22 ScoringError::InvalidInput(message.into())
23}
24
25pub(crate) fn require_finite(value: f64, name: &str) -> ScoringResult<()> {
26 if value.is_finite() {
27 Ok(())
28 } else {
29 Err(invalid_input(format!("{name} must be finite, got {value}")))
30 }
31}
32
33pub(crate) fn require_probability(value: f64, name: &str) -> ScoringResult<()> {
34 require_finite(value, name)?;
35 if (0.0..=1.0).contains(&value) {
36 Ok(())
37 } else {
38 Err(invalid_input(format!(
39 "{name} must be in [0, 1], got {value}"
40 )))
41 }
42}