devela/code/error/
all_error.rs

1// devela::code::error::all_error
2//
3//! Defines the [`AllError`] enum.
4//
5// TOC
6// - individual errors:
7//   - InvalidErrorConversion
8//   - NotImplemented
9//   - NotSupported
10// - composite errors:
11//   - AllResult
12//   - AllError
13
14use crate::define_error;
15
16define_error![individual: pub struct FailedErrorConversion;
17    DOC_FAILED_CONVERSION = "A failed conversion between two error types.",
18    self+f => write!(f, "Failed to convert between error types"),
19];
20define_error![individual: pub struct NotImplemented;
21    DOC_NOT_IMPLEMENTED = "The requested functionality is not implemented.",
22    self+f => write!(f, "The requested functionality is not implemented."),
23];
24define_error![individual: pub struct NotSupported;
25    DOC_NOT_SUPPORTED = "The requested functionality is not supported by this type.",
26    self+f => write!(f, "The requested functionality is not supported by this type."),
27];
28
29/* composite errors: */
30
31define_error! { composite: fmt(f)
32    /// An error composite of [`NotImplemented`] + [`NotSupported`].
33    ///
34    /// Used in methods of:
35    /// - [`DataCollection`][crate::DataCollection].
36    pub enum NotAvailable {
37        DOC_NOT_IMPLEMENTED: NotImplemented => NotImplemented,
38        DOC_NOT_SUPPORTED: NotSupported => NotSupported,
39    }
40}
41
42#[cfg(feature = "error")]
43pub use full_composite::*;
44#[cfg_attr(nightly_doc, doc(cfg(feature = "error")))]
45#[cfg(feature = "error")]
46mod full_composite {
47    use super::super::reexports::crate_errors::*;
48    #[cfg(feature = "time")]
49    use crate::TimeError; /* TEMP */
50    // use super::*;
51
52    #[doc = crate::TAG_RESULT!()]
53    /// The root result type, aggregating all module-specific results.
54    pub type AllResult<T> = crate::Result<T, AllError>;
55
56    #[doc = crate::TAG_ERROR_COMPOSITE!()]
57    /// The root error type, aggregating all module-specific errors.
58    ///
59    /// This error is designed to encompass all possible errors within the library's domain,
60    /// providing a unified interface for error handling across modules.
61    ///
62    /// See also: [`AllErrorKind`].
63    #[derive(Debug)]
64    pub enum AllError {
65        /// A data-related error.
66        #[cfg(data··)]
67        #[cfg_attr(nightly_doc, doc(cfg(data··)))]
68        Data(DataError),
69
70        /// A numeric-related error.
71        Num(NumError),
72
73        // IMPROVE Sys
74        /// An I/O-related error.
75        #[cfg(feature = "io")]
76        #[cfg_attr(nightly_doc, doc(cfg(feature = "io")))]
77        Io(IoError),
78
79        /// A text-related error.
80        #[cfg(text··)]
81        #[cfg_attr(nightly_doc, doc(cfg(text··)))]
82        Text(TextError),
83
84        // IMPROVE Phys
85        /// A time-related error.
86        #[cfg(feature = "time")]
87        #[cfg_attr(nightly_doc, doc(cfg(feature = "time")))]
88        Time(TimeError),
89
90        /// Other static error.
91        Other(&'static str),
92    }
93
94    #[doc = crate::TAG_ERROR_COMPOSITE!()]
95    /// The kind of root error type, aggregating all module-specific error kinds.
96    ///
97    /// See also: [`AllError`].
98    #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
99    pub enum AllErrorKind {
100        /// A data-related error.
101        #[cfg(data··)]
102        #[cfg_attr(nightly_doc, doc(cfg(data··)))]
103        Data(()), // TODO
104
105        /// A numeric-related error.
106        Num(()), // TODO
107
108        /// An I/O error.
109        #[cfg(feature = "io")]
110        #[cfg_attr(nightly_doc, doc(cfg(feature = "io")))]
111        Io(IoErrorKind),
112
113        /// A time error.
114        #[cfg(feature = "time")]
115        #[cfg_attr(nightly_doc, doc(cfg(feature = "time")))]
116        Time(()), // TODO
117
118        /// A text-related error.
119        #[cfg(text··)]
120        #[cfg_attr(nightly_doc, doc(cfg(text··)))]
121        Text(()), // TODO
122
123        /// Other static error.
124        Other,
125        // /// No error kind.
126        // #[default]
127        // None, // MAYBE
128    }
129
130    mod core_impls {
131        use super::*;
132        use crate::impl_trait;
133
134        impl crate::Error for AllError {}
135        impl crate::ExtError for AllError {
136            type Kind = AllErrorKind;
137
138            fn error_eq(&self, other: &Self) -> bool {
139                use AllError as E;
140                match (self, other) {
141                    #[cfg(data··)]
142                    (E::Data(e1), E::Data(e2)) => e1.error_eq(e2),
143                    (E::Num(e1), E::Num(e2)) => e1.error_eq(e2),
144                    #[cfg(feature = "io")]
145                    (E::Io(e1), E::Io(e2)) => e1.error_eq(e2),
146                    #[cfg(feature = "time")]
147                    (E::Time(e1), E::Time(e2)) => e1.error_eq(e2),
148                    #[cfg(text··)]
149                    (E::Text(e1), E::Text(e2)) => e1.error_eq(e2),
150                    (E::Other(s1), E::Other(s2)) => s1 == s2,
151
152                    _ => false, // Different variants cannot be equal.
153                }
154            }
155            fn error_kind(&self) -> Self::Kind {
156                use {AllError as E, AllErrorKind as K};
157                #[expect(clippy::unit_arg, reason = "WIP () placeholder")]
158                match self {
159                    #[cfg(data··)]
160                    E::Data(e) => K::Data(e.error_kind()),
161                    E::Num(e) => K::Num(e.error_kind()),
162                    #[cfg(feature = "io")]
163                    E::Io(e) => K::Io(e.error_kind()),
164                    #[cfg(feature = "time")]
165                    E::Time(e) => K::Time(e.error_kind()),
166                    #[cfg(text··)]
167                    E::Text(e) => K::Text(e.error_kind()),
168                    E::Other(_s) => K::Other,
169                }
170            }
171        }
172
173        impl_trait! { fmt::Display for AllError |self, f| {
174            use AllError as E;
175            match self {
176                #[cfg(data··)]
177                E::Data(e) => write!(f, "{e:?}"),
178                E::Num(e) => write!(f, "{e:?}"),
179                #[cfg(feature = "io")]
180                E::Io(e) => write!(f, "{e:?}"),
181                #[cfg(feature = "time")]
182                E::Time(e) => write!(f, "{e:?}"),
183                #[cfg(text··)]
184                E::Text(e) => write!(f, "{e:?}"),
185                E::Other(s) => write!(f, "{s}"),
186            }
187        }}
188    }
189}