1use core::fmt;
2use std::error::Error;
3
4#[derive(Debug, Clone, Copy, PartialEq)]
6pub enum RealError {
7 NonFiniteValue {
9 name: &'static str,
11 value: f64,
13 },
14 NonFiniteTolerance(f64),
16 NegativeTolerance(f64),
18 InvalidInterval {
20 min: f64,
22 max: f64,
24 },
25}
26
27impl RealError {
28 pub(crate) const fn validate_value(name: &'static str, value: f64) -> Result<f64, Self> {
29 if !value.is_finite() {
30 return Err(Self::NonFiniteValue { name, value });
31 }
32
33 Ok(value)
34 }
35
36 pub(crate) const fn validate_tolerance(tolerance: f64) -> Result<f64, Self> {
37 if !tolerance.is_finite() {
38 return Err(Self::NonFiniteTolerance(tolerance));
39 }
40
41 if tolerance < 0.0 {
42 return Err(Self::NegativeTolerance(tolerance));
43 }
44
45 Ok(tolerance)
46 }
47}
48
49impl fmt::Display for RealError {
50 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
51 match self {
52 Self::NonFiniteValue { name, value } => {
53 write!(formatter, "{name} must be finite, got {value}")
54 },
55 Self::NonFiniteTolerance(value) => {
56 write!(formatter, "tolerance must be finite, got {value}")
57 },
58 Self::NegativeTolerance(value) => {
59 write!(formatter, "tolerance must be non-negative, got {value}")
60 },
61 Self::InvalidInterval { min, max } => {
62 write!(
63 formatter,
64 "interval min must not exceed max, got min={min}, max={max}"
65 )
66 },
67 }
68 }
69}
70
71impl Error for RealError {}