devela/data/error/
definitions.rs

1// devela::data::error::definitions
2//
3//!
4//
5// TOC
6// - individual data-related error types:
7//   - DataOverflow
8//   - ElementNotFound
9//   - IndexOutOfBounds
10//   - InvalidAxisLength
11//   - KeyAlreadyExists
12//   - MismatchedCapacity
13//   - MismatchedDimensions
14//   - MismatchedIndices
15//   - NodeEmpty
16//   - NodeLinkNotSet
17//   - NodeLinkNotUnique
18//   - NotEnoughElements
19//   - NotEnoughSpace
20//   - PartiallyAdded
21// - partial composite errors:
22//   - DataNotEnough:    NotEnoughElements, NotEnoughSpace
23//   - MismatchedBounds: DataOverflow, IndexOutOfBounds, MismatchedIndices, MismatchedCapacity
24//   - PartialSpace:     NotEnoughSpace, PartiallyAdded
25// - full composite errors:
26//   - DataError
27//   - DataResult
28
29use crate::{impl_error, Interval, Mismatch};
30
31/* individual errors */
32
33impl_error! { individual: pub struct DataOverflow(pub Option<usize>);
34    DOC_DATA_OVERFLOW = "The value has surpassed the bounds of the representable data space.",
35    self+f => if let Some(v) = self.0 {
36        write!(f, "The value {v} has surpassed the bounds of the representable data space.")
37    } else { write!(f, "The value has surpassed the bounds of the representable data space.") }
38}
39impl_error! { individual: pub struct ElementNotFound;
40    DOC_ELEMENT_NOT_FOUND = "The requested element has not been found.",
41    self+f => write!(f, "The requested element has not been found."),
42}
43impl_error! { individual: pub struct IndexOutOfBounds(pub Option<usize>);
44    DOC_INDEX_OUT_OF_BOUNDS = "The given index is out of bounds.\n\n
45Optionally contains the given index.",
46    self+f => if let Some(i) = self.0 { write!(f, "The given index {i} is out of bounds.")
47    } else { write!(f, "The given index is out of bounds.") }
48}
49impl_error! { individual: pub struct InvalidAxisLength(pub Option<usize>);
50    DOC_INVALID_AXIS_LENGTH = "The given axis has an invalid length.\n\n
51Optionally contains the given axis number.",
52    self+f => if let Some(n) = self.0 {
53        write!(f, "Axis number {n} has 0 length, which is not allowed.")
54    } else { write!(f, "One ore more axis have 0 length, which is not allowed.") }
55}
56impl_error! { individual: pub struct KeyAlreadyExists;
57    DOC_KEY_ALREADY_EXISTS = "The key already exists.",
58    self+f => write!(f, "The key already exists.")
59}
60impl_error! { individual: pub struct MismatchedCapacity(pub Mismatch<Interval<usize>, usize>);
61    DOC_MISMATCHED_CAPACITY = "The given capacity did not match the required constraints.",
62    self+f => write!(f, "Mismatched capacity: {:?}.", self.0)
63}
64impl MismatchedCapacity {
65    /// Creates a mismatch where `need` is an [`Interval::closed`], and `have` is outside it.
66    #[must_use]
67    pub const fn closed(lower: usize, upper: usize, have: usize) -> Self {
68        Self(Mismatch::in_closed_interval(lower, upper, have, DOC_MISMATCHED_CAPACITY!()))
69    }
70    /// Creates a mismatch where `need` is an [`Interval::closed_open`], and `have` is outside it.
71    #[must_use]
72    pub const fn closed_open(lower: usize, upper: usize, have: usize) -> Self {
73        Self(Mismatch::in_closed_open_interval(lower, upper, have, DOC_MISMATCHED_CAPACITY!()))
74    }
75}
76impl_error! { individual: pub struct MismatchedDimensions(pub Mismatch<usize, usize>);
77    DOC_MISMATCHED_DIMENSIONS = "The dimensions given did not match the elements provided.",
78    self+f => write!(f, "Mismatched dimensions: {:?}.", self.0)
79}
80impl_error! { individual: pub struct MismatchedIndices;
81    DOC_MISMATCHED_INDICES = "The given indices does not match the expected order.",
82    self+f => write!(f, "The given indices does not match the expected order.")
83}
84impl_error! { individual: pub struct NodeEmpty(pub Option<usize>);
85    DOC_NODE_EMPTY = "The node is empty.",
86    self+f => if let Some(n) = self.0 { write!(f, "The given node `{n}` is empty.")
87    } else { write!(f, "The node is empty.") }
88}
89impl_error! { individual: pub struct NodeLinkNotSet(pub Option<usize>);
90    DOC_NODE_LINK_NOT_SET = "The link is not set.",
91    self+f => if let Some(n) = self.0 { write!(f, "The given node link `{n}` is not set.")
92    } else { write!(f, "The node link is not set.") }
93}
94impl_error! { individual: pub struct NodeLinkNotUnique(pub Option<usize>);
95    DOC_NODE_LINK_NOT_UNIQUE = "The link is not unique.",
96    self+f => if let Some(n) = self.0 { write!(f, "The given node link `{n}` is not unique.")
97    } else { write!(f, "The node link is not unique.") }
98}
99impl_error! { individual: pub struct NotEnoughElements(pub Option<usize>);
100    DOC_NOT_ENOUGH_ELEMENTS = "There are not enough elements for the operation.\n\n
101Optionally contains the minimum number of elements needed.",
102    self+f => if let Some(n) = self.0 {
103        write!(f, "Not enough elements. Needs at least `{n}` elements.")
104    } else { write!(f, "Not enough elements.") }
105}
106impl_error! { individual: pub struct NotEnoughSpace(pub Option<usize>);
107    DOC_NOT_ENOUGH_SPACE = "There is not enough free space for the operation.\n\n
108Optionally contains the number of free spaces needed.",
109    self+f => if let Some(n) = self.0 {
110        write!(f, "Not enough space. Needs at least `{n}` free space for elements.")
111    } else { write!(f, "Not enough space.") }
112}
113impl_error! { individual: pub struct PartiallyAdded(pub Option<usize>);
114    DOC_PARTIALLY_ADDED = "The operation could only add a subset of the elements.\n\n
115Optionally contains the number of elements added.",
116    self+f => if let Some(n) = self.0 { write!(f, "Only `{n}` elements could be added.")
117    } else { write!(f, "Only a subset of elements could be added.") }
118}
119
120/* composite errors */
121
122impl_error! { composite: fmt(f)
123    /// An error composite of [`NotEnoughElements`] + [`NotEnoughSpace`].
124    ///
125    /// Used in methods of:
126    /// [`Destaque`][crate::Destaque],
127    /// [`Stack`][crate::Stack].
128    pub enum DataNotEnough {
129        DOC_NOT_ENOUGH_ELEMENTS:    Elements(i|0: Option<usize>)  => NotEnoughElements(*i),
130        DOC_NOT_ENOUGH_SPACE:       Space(i|0: Option<usize>)     => NotEnoughSpace(*i),
131    }
132}
133impl_error! { composite: fmt(f)
134    /// An error composite of
135    /// [`DataOverflow`] + [`IndexOutOfBounds`] +
136    /// [`MismatchedIndices`] + [`MismatchedCapacity`].
137    ///
138    /// Used in methods of:
139    /// [`Array`][crate::Array],
140    /// [`Array2d`][crate::Array2d],
141    /// [`bitfield!`][crate::bitfield],
142    /// [`BitOps`][crate::BitOps],
143    /// [`Bitwise`][crate::Bitwise].
144    pub enum MismatchedBounds {
145        DOC_DATA_OVERFLOW:
146            DataOverflow(i|0: Option<usize>) => DataOverflow(*i),
147        DOC_INDEX_OUT_OF_BOUNDS:
148            IndexOutOfBounds(i|0: Option<usize>) => IndexOutOfBounds(*i),
149        DOC_MISMATCHED_CAPACITY:
150            MismatchedCapacity(c|0: Mismatch<Interval<usize>, usize>) => MismatchedCapacity(*c),
151        DOC_MISMATCHED_INDICES:
152            MismatchedIndices => MismatchedIndices,
153    }
154}
155// MAYBE: Merge with DataNotEnough
156impl_error! { composite: fmt(f)
157    /// An error composite of [`NotEnoughSpace`] + [`PartiallyAdded`].
158    ///
159    /// Used in methods of:
160    /// [`ArrayUninit`][crate::ArrayUninit].
161    pub enum PartialSpace {
162        DOC_NOT_ENOUGH_SPACE:   NotEnoughSpace(i|0: Option<usize>) => NotEnoughSpace(*i),
163        DOC_PARTIALLY_ADDED:    PartiallyAdded(i|0: Option<usize>) => PartiallyAdded(*i),
164    }
165}
166
167#[cfg(all(feature = "error", data··))]
168pub use full_composite::*;
169#[cfg(all(feature = "error", data··))]
170#[cfg_attr(feature = "nightly_doc", doc(cfg(all(feature = "error", data··))))]
171mod full_composite {
172    use super::*;
173    use crate::{
174        NotAvailable, NotImplemented, NotSupported, DOC_NOT_IMPLEMENTED, DOC_NOT_SUPPORTED,
175    };
176
177    impl_error! { composite: fmt(f)
178        /// A data-related composite error.
179        #[non_exhaustive]
180        pub enum DataError {
181            DOC_NOT_IMPLEMENTED: NotImplemented => NotImplemented,
182            DOC_NOT_SUPPORTED: NotSupported => NotSupported,
183            //
184            DOC_DATA_OVERFLOW:
185                DataOverflow(i|0: Option<usize>) => DataOverflow(*i),
186            DOC_ELEMENT_NOT_FOUND:
187                ElementNotFound => ElementNotFound,
188            DOC_INDEX_OUT_OF_BOUNDS:
189                IndexOutOfBounds(i|0: Option<usize>) => IndexOutOfBounds(*i),
190            DOC_INVALID_AXIS_LENGTH:
191                InvalidAxisLength(i|0: Option<usize>) => InvalidAxisLength(*i),
192            DOC_KEY_ALREADY_EXISTS:
193                KeyAlreadyExists => KeyAlreadyExists,
194            DOC_MISMATCHED_CAPACITY:
195                MismatchedCapacity(c|0: Mismatch<Interval<usize>, usize>) => MismatchedCapacity(*c),
196            DOC_MISMATCHED_DIMENSIONS:
197                MismatchedDimensions(d|0: Mismatch<usize, usize>) => MismatchedDimensions(*d),
198            DOC_MISMATCHED_INDICES:
199                MismatchedIndices => MismatchedIndices,
200            DOC_NODE_EMPTY:
201                NodeEmpty(i|0: Option<usize>) => NodeEmpty(*i),
202            DOC_NODE_LINK_NOT_SET:
203                NodeLinkNotSet(i|0: Option<usize>) => NodeLinkNotSet(*i),
204            DOC_NODE_LINK_NOT_UNIQUE:
205                NodeLinkNotUnique(i|0: Option<usize>) => NodeLinkNotUnique(*i),
206            DOC_NOT_ENOUGH_ELEMENTS:
207                NotEnoughElements(i|0: Option<usize>) => NotEnoughElements(*i),
208            DOC_NOT_ENOUGH_SPACE:
209                NotEnoughSpace(i|0: Option<usize>) => NotEnoughSpace(*i),
210            DOC_PARTIALLY_ADDED:
211                PartiallyAdded(i|0: Option<usize>) => PartiallyAdded(*i),
212        }
213    }
214    impl_error! { composite: from(f): NotAvailable, for: DataError {
215        NotImplemented => NotImplemented,
216        NotSupported => NotSupported,
217    }}
218    impl_error! { composite: from(f): DataNotEnough, for: DataError {
219        Elements(i) => NotEnoughElements(i),
220        Space(i) => NotEnoughSpace(i),
221    }}
222    impl_error! { composite: from(f): PartialSpace, for: DataError {
223        NotEnoughSpace(i) => NotEnoughSpace(i),
224        PartiallyAdded(i) => PartiallyAdded(i),
225    }}
226    impl_error! { composite: from(f): MismatchedBounds, for: DataError {
227        DataOverflow(i) => DataOverflow(i),
228        IndexOutOfBounds(i) => IndexOutOfBounds(i),
229        MismatchedCapacity(i) => MismatchedCapacity(i),
230        MismatchedIndices => MismatchedIndices,
231    }}
232
233    #[doc = crate::TAG_RESULT!()]
234    /// A data-related result.
235    pub type DataResult<T> = crate::Result<T, DataError>;
236}