devela/num/
error.rs

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