devela/num/
error.rs

1// devela::num::error
2//
3//!
4//
5
6#[expect(unused, reason = "WIP")]
7use crate::{impl_error, Sign};
8
9// Requires PartialOrd and Ord? Remove
10// impl_error! { individual: Overflow(Option<Sign>),
11//     DOC_OVERFLOW = "An arithmetic overflow error, with an optional associated sign.",
12//     self+f => if let Some(sign) = self.0 {
13//         match sign {
14//             Sign::Positive => write!(f, "Positive overflow."),
15//             Sign::Negative => write!(f, "Negative overflow."),
16//             Sign::None => write!(f, "Unsigned overflow."), // not meaningful
17//         }
18//     } else { write!(f, "Overflow.") }
19// }
20
21// DELETE
22// impl_error! { individual: ElementNotFound,
23//     DOC_ELEMENT_NOT_FOUND = "The requested element has not been found.",
24//     self+f => write!(f, "The requested element has not been found."),
25// }
26// impl_error! { individual: InvalidAxisLength(pub Option<usize>),
27//     DOC_INVALID_AXIS_LENGTH = "The given axis has an invalid length.\n\n
28// Optionally contains some given axis number.",
29//     self+f => if let Some(n) = self.0 {
30//         write!(f, "Axis number {n} has 0 length, which is not allowed.")
31//     } else { write!(f, "One ore more axis have 0 length, which is not allowed.") }
32// }
33
34#[doc = crate::TAG_RESULT!()]
35/// A numeric-related result.
36pub type NumResult<T> = crate::Result<T, NumError>;
37
38#[doc = crate::TAG_ERROR_COMPOSITE!()]
39/// A numeric-related error.
40#[non_exhaustive]
41#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
42pub enum NumError {
43    /// The requested numerical functionality is not implemented.
44    ///
45    /// This is the default implementation of every numeric trait method.
46    NotImplemented,
47
48    /// The requested numerical functionality is not supported.
49    NotSupported,
50
51    /// Unspecified error.
52    ///
53    /// When no clearer error can be given.
54    // RETHINK
55    Unspecified,
56
57    /// An invalid value was received for the given type or operation.
58    Invalid,
59
60    /// An inverse doesn't exist.
61    NoInverse,
62
63    /// The provided values are not compatible in size.
64    MismatchedSizes,
65
66    /// The given bounds are not compatible.
67    IncompatibleBounds,
68
69    /// A non-negative value is required.
70    NonNegativeRequired,
71
72    /// A positive value is required.
73    PositiveRequired,
74
75    /// A non-zero value is required.
76    NonZeroRequired,
77
78    /// An arithmetic overflow error, with an optional associated sign.
79    Overflow(Option<Sign>),
80}
81
82#[allow(dead_code)]
83impl NumError {
84    pub(crate) const fn ni<T>() -> NumResult<T> {
85        Err(NumError::NotImplemented)
86    }
87    pub(crate) const fn ns<T>() -> NumResult<T> {
88        Err(NumError::NotSupported)
89    }
90}
91
92mod core_impls {
93    use crate::{Display, FmtResult, Formatter, NumError, Sign};
94
95    impl crate::Error for NumError {}
96    impl crate::ExtError for NumError {
97        type Kind = ();
98        fn error_eq(&self, other: &Self) -> bool {
99            self == other
100        }
101        fn error_kind(&self) -> Self::Kind {}
102    }
103
104    impl Display for NumError {
105        fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult<()> {
106            use NumError as E;
107            match self {
108                E::NotImplemented => write!(f, "Not implemented."),
109                E::NotSupported => write!(f, "Not supported."),
110                E::Unspecified => write!(f, "Unspecified."),
111                E::Invalid => write!(f, "Invalid value."),
112                E::NoInverse => write!(f, "An inverse doesn't exist."),
113                E::IncompatibleBounds => {
114                    write!(f, "The given bounds are incompatible.")
115                }
116                E::MismatchedSizes => {
117                    write!(f, "The provided values are not compatible in size.")
118                }
119                E::NonNegativeRequired => write!(f, "A non-negative value is required."),
120                E::PositiveRequired => write!(f, "A positive value is required.."),
121                E::NonZeroRequired => write!(f, "A non-zero value is required."),
122                E::Overflow(sign) => {
123                    if let Some(sign) = sign {
124                        match sign {
125                            Sign::Positive => write!(f, "Positive overflow."),
126                            Sign::Negative => write!(f, "Negative overflow."),
127                            Sign::None => write!(f, "Unsigned overflow."), // not meaningful
128                        }
129                    } else {
130                        write!(f, "Overflow.")
131                    }
132                }
133            }
134        }
135    }
136}