1use crate::misc::{InvalidSentinel, Saturated, SignedInfinity};
8use core::fmt::{self, Debug, Display};
9
10#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, thiserror::Error)]
15pub enum GeneralError<T> {
16 #[error("conversion resulted in negative overflow")]
18 NegOverflow(T),
19
20 #[error("conversion resulted in positive overflow")]
22 PosOverflow(T),
23
24 #[error("could not convert unrepresentable value")]
26 Unrepresentable(T),
27}
28
29impl<T> GeneralError<T> {
30 pub fn into_inner(self) -> T {
32 match self {
33 GeneralError::NegOverflow(v)
34 | GeneralError::PosOverflow(v)
35 | GeneralError::Unrepresentable(v) => v,
36 }
37 }
38}
39
40impl<T> From<NoError> for GeneralError<T> {
41 fn from(_: NoError) -> Self {
42 unreachable!();
43 }
44}
45
46impl<T> From<Unrepresentable<T>> for GeneralError<T> {
47 fn from(e: Unrepresentable<T>) -> Self {
48 GeneralError::Unrepresentable(e.0)
49 }
50}
51
52impl<T> From<NegOverflow<T>> for GeneralError<T> {
53 fn from(e: NegOverflow<T>) -> Self {
54 GeneralError::NegOverflow(e.0)
55 }
56}
57
58impl<T> From<PosOverflow<T>> for GeneralError<T> {
59 fn from(e: PosOverflow<T>) -> Self {
60 GeneralError::PosOverflow(e.0)
61 }
62}
63
64impl<T> From<RangeError<T>> for GeneralError<T> {
65 fn from(e: RangeError<T>) -> Self {
66 match e {
67 RangeError::NegOverflow(v) => GeneralError::NegOverflow(v),
68 RangeError::PosOverflow(v) => GeneralError::PosOverflow(v),
69 }
70 }
71}
72
73impl<T> From<FloatError<T>> for GeneralError<T> {
74 fn from(e: FloatError<T>) -> GeneralError<T> {
75 use self::FloatError as F;
76 use self::GeneralError as G;
77 match e {
78 F::NegOverflow(v) => G::NegOverflow(v),
79 F::PosOverflow(v) => G::PosOverflow(v),
80 F::NotANumber(v) => G::Unrepresentable(v),
81 }
82 }
83}
84
85#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, thiserror::Error)]
91pub enum GeneralErrorKind {
92 #[error("conversion resulted in negative overflow")]
94 NegOverflow,
95
96 #[error("conversion resulted in positive overflow")]
98 PosOverflow,
99
100 #[error("could not convert unrepresentable value")]
102 Unrepresentable,
103}
104
105impl From<NoError> for GeneralErrorKind {
106 fn from(_: NoError) -> Self {
107 unreachable!();
108 }
109}
110
111impl<T> From<Unrepresentable<T>> for GeneralErrorKind {
112 fn from(_: Unrepresentable<T>) -> Self {
113 GeneralErrorKind::Unrepresentable
114 }
115}
116
117impl<T> From<NegOverflow<T>> for GeneralErrorKind {
118 fn from(_: NegOverflow<T>) -> Self {
119 GeneralErrorKind::NegOverflow
120 }
121}
122
123impl<T> From<PosOverflow<T>> for GeneralErrorKind {
124 fn from(_: PosOverflow<T>) -> Self {
125 GeneralErrorKind::PosOverflow
126 }
127}
128
129impl From<RangeErrorKind> for GeneralErrorKind {
130 fn from(e: RangeErrorKind) -> Self {
131 match e {
132 RangeErrorKind::NegOverflow => GeneralErrorKind::NegOverflow,
133 RangeErrorKind::PosOverflow => GeneralErrorKind::PosOverflow,
134 }
135 }
136}
137impl<T> From<RangeError<T>> for GeneralErrorKind {
138 fn from(e: RangeError<T>) -> Self {
139 match e {
140 RangeError::NegOverflow(..) => GeneralErrorKind::NegOverflow,
141 RangeError::PosOverflow(..) => GeneralErrorKind::PosOverflow,
142 }
143 }
144}
145impl<T> From<GeneralError<T>> for GeneralErrorKind {
146 fn from(e: GeneralError<T>) -> Self {
147 match e {
148 GeneralError::NegOverflow(..) => GeneralErrorKind::NegOverflow,
149 GeneralError::PosOverflow(..) => GeneralErrorKind::PosOverflow,
150 GeneralError::Unrepresentable(..) => GeneralErrorKind::Unrepresentable,
151 }
152 }
153}
154
155impl<T> From<FloatError<T>> for GeneralErrorKind {
156 fn from(e: FloatError<T>) -> GeneralErrorKind {
157 use self::FloatError as F;
158 use self::GeneralErrorKind as G;
159 match e {
160 F::NegOverflow(..) => G::NegOverflow,
161 F::PosOverflow(..) => G::PosOverflow,
162 F::NotANumber(..) => G::Unrepresentable,
163 }
164 }
165}
166
167#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
173pub enum NoError {}
174
175impl Display for NoError {
176 fn fmt(&self, _: &mut fmt::Formatter) -> Result<(), fmt::Error> {
177 unreachable!()
178 }
179}
180
181impl std::error::Error for NoError {}
182
183#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, thiserror::Error)]
185#[error("could not convert unrepresentable value")]
186pub struct Unrepresentable<T>(pub T);
187
188impl<T> From<NoError> for Unrepresentable<T> {
189 fn from(_: NoError) -> Self {
190 unreachable!();
191 }
192}
193
194#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, thiserror::Error)]
196#[error("conversion resulted in negative overflow")]
197pub struct NegOverflow<T>(pub T);
198
199impl<T> From<NoError> for NegOverflow<T> {
200 fn from(_: NoError) -> Self {
201 unreachable!();
202 }
203}
204
205#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, thiserror::Error)]
207#[error("conversion resulted in positive overflow")]
208pub struct PosOverflow<T>(pub T);
209
210impl<T> From<NoError> for PosOverflow<T> {
211 fn from(_: NoError) -> Self {
212 unreachable!();
213 }
214}
215
216#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, thiserror::Error)]
218pub enum FloatError<T> {
219 #[error("conversion resulted in negative overflow")]
221 NegOverflow(T),
222
223 #[error("conversion resulted in positive overflow")]
225 PosOverflow(T),
226
227 #[error("conversion target does not support not-a-number")]
229 NotANumber(T),
230}
231
232impl<T> FloatError<T> {
233 pub fn into_inner(self) -> T {
235 match self {
236 FloatError::NegOverflow(v) | FloatError::PosOverflow(v) | FloatError::NotANumber(v) => {
237 v
238 }
239 }
240 }
241}
242
243impl<T> From<NoError> for FloatError<T> {
244 fn from(_: NoError) -> Self {
245 unreachable!();
246 }
247}
248
249impl<T> From<NegOverflow<T>> for FloatError<T> {
250 fn from(e: NegOverflow<T>) -> Self {
251 FloatError::NegOverflow(e.0)
252 }
253}
254
255impl<T> From<PosOverflow<T>> for FloatError<T> {
256 fn from(e: PosOverflow<T>) -> Self {
257 FloatError::PosOverflow(e.0)
258 }
259}
260
261impl<T> From<RangeError<T>> for FloatError<T> {
262 fn from(e: RangeError<T>) -> Self {
263 match e {
264 RangeError::NegOverflow(v) => FloatError::NegOverflow(v),
265 RangeError::PosOverflow(v) => FloatError::PosOverflow(v),
266 }
267 }
268}
269
270#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, thiserror::Error)]
272pub enum RangeError<T> {
273 #[error("conversion resulted in negative overflow")]
275 NegOverflow(T),
276
277 #[error("conversion resulted in positive overflow")]
279 PosOverflow(T),
280}
281
282impl<T> From<NoError> for RangeError<T> {
283 fn from(_: NoError) -> Self {
284 unreachable!();
285 }
286}
287
288impl<T> From<NegOverflow<T>> for RangeError<T> {
289 fn from(e: NegOverflow<T>) -> Self {
290 RangeError::NegOverflow(e.0)
291 }
292}
293
294impl<T> From<PosOverflow<T>> for RangeError<T> {
295 fn from(e: PosOverflow<T>) -> Self {
296 RangeError::PosOverflow(e.0)
297 }
298}
299
300#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, thiserror::Error)]
307pub enum RangeErrorKind {
308 #[error("conversion resulted in negative overflow")]
310 NegOverflow,
311
312 #[error("conversion resulted in positive overflow")]
314 PosOverflow,
315}
316
317impl From<NoError> for RangeErrorKind {
318 fn from(_: NoError) -> Self {
319 unreachable!();
320 }
321}
322
323impl<T> From<NegOverflow<T>> for RangeErrorKind {
324 fn from(_: NegOverflow<T>) -> Self {
325 RangeErrorKind::NegOverflow
326 }
327}
328
329impl<T> From<PosOverflow<T>> for RangeErrorKind {
330 fn from(_: PosOverflow<T>) -> Self {
331 RangeErrorKind::PosOverflow
332 }
333}
334
335impl<T> From<RangeError<T>> for RangeErrorKind {
336 fn from(e: RangeError<T>) -> Self {
337 match e {
338 RangeError::NegOverflow(..) => RangeErrorKind::NegOverflow,
339 RangeError::PosOverflow(..) => RangeErrorKind::PosOverflow,
340 }
341 }
342}
343
344pub trait Saturate {
346 type Output;
348
349 fn saturate(self) -> Self::Output;
357}
358
359impl<T, U> Saturate for Result<T, FloatError<U>>
360where
361 T: Saturated,
362{
363 type Output = Result<T, Unrepresentable<U>>;
364
365 fn saturate(self) -> Self::Output {
366 use self::FloatError::*;
367 match self {
368 Ok(v) => Ok(v),
369 Err(NegOverflow(_)) => Ok(T::saturated_min()),
370 Err(PosOverflow(_)) => Ok(T::saturated_max()),
371 Err(NotANumber(v)) => Err(Unrepresentable(v)),
372 }
373 }
374}
375
376impl<T, U> Saturate for Result<T, RangeError<U>>
377where
378 T: Saturated,
379{
380 type Output = Result<T, NoError>;
381
382 fn saturate(self) -> Self::Output {
383 use self::RangeError::*;
384 match self {
385 Ok(v) => Ok(v),
386 Err(NegOverflow(_)) => Ok(T::saturated_min()),
387 Err(PosOverflow(_)) => Ok(T::saturated_max()),
388 }
389 }
390}
391
392impl<T> Saturate for Result<T, RangeErrorKind>
393where
394 T: Saturated,
395{
396 type Output = Result<T, NoError>;
397
398 fn saturate(self) -> Self::Output {
399 use self::RangeErrorKind::*;
400 match self {
401 Ok(v) => Ok(v),
402 Err(NegOverflow) => Ok(T::saturated_min()),
403 Err(PosOverflow) => Ok(T::saturated_max()),
404 }
405 }
406}
407
408pub trait UnwrapOk<T> {
410 fn unwrap_ok(self) -> T;
415}
416
417impl<T> UnwrapOk<T> for Result<T, NoError> {
418 fn unwrap_ok(self) -> T {
419 match self {
420 Ok(v) => v,
421 Err(no_error) => match no_error {},
422 }
423 }
424}
425
426pub trait UnwrapOrInf {
428 type Output;
430
431 fn unwrap_or_inf(self) -> Self::Output;
434}
435
436pub trait UnwrapOrInvalid {
438 type Output;
440
441 fn unwrap_or_invalid(self) -> Self::Output;
444}
445
446pub trait UnwrapOrSaturate {
448 type Output;
450
451 fn unwrap_or_saturate(self) -> Self::Output;
454}
455
456impl<T, E> UnwrapOrInf for Result<T, E>
457where
458 T: SignedInfinity,
459 E: Into<RangeErrorKind>,
460{
461 type Output = T;
462 fn unwrap_or_inf(self) -> T {
463 use self::RangeErrorKind::*;
464 match self.map_err(Into::into) {
465 Ok(v) => v,
466 Err(NegOverflow) => T::neg_infinity(),
467 Err(PosOverflow) => T::pos_infinity(),
468 }
469 }
470}
471
472impl<T, E> UnwrapOrInvalid for Result<T, E>
473where
474 T: InvalidSentinel,
475{
476 type Output = T;
477 fn unwrap_or_invalid(self) -> T {
478 match self {
479 Ok(v) => v,
480 Err(..) => T::invalid_sentinel(),
481 }
482 }
483}
484
485impl<T, E> UnwrapOrSaturate for Result<T, E>
486where
487 T: Saturated,
488 E: Into<RangeErrorKind>,
489{
490 type Output = T;
491 fn unwrap_or_saturate(self) -> T {
492 use self::RangeErrorKind::*;
493 match self.map_err(Into::into) {
494 Ok(v) => v,
495 Err(NegOverflow) => T::saturated_min(),
496 Err(PosOverflow) => T::saturated_max(),
497 }
498 }
499}