overflow_error/
lib.rs

1//! Common overflow error types.
2
3#![cfg_attr(not(any(test, feature = "std")), no_std)]
4#![forbid(missing_docs, missing_debug_implementations)]
5#![cfg_attr(test, deny(warnings))]
6#![feature(never_type)]
7
8#[cfg(any(test, feature = "std"))]
9extern crate core;
10use core::fmt;
11
12extern crate failure;
13use failure::Fail;
14
15// TODO: impl Hash
16/// A discrete error with a known description.
17pub trait Error: Fail + Copy + Eq {
18    /// Describes the error using a static string.
19    fn describe(self) -> &'static str;
20}
21impl Error for ! {
22    fn describe(self) -> &'static str {
23        self
24    }
25}
26
27/// Division could not be performed due to division by zero.
28#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
29pub struct DivByZero;
30impl Fail for DivByZero {}
31impl Error for DivByZero {
32    #[inline]
33    fn describe(self) -> &'static str {
34        "division by zero"
35    }
36}
37impl fmt::Display for DivByZero {
38    #[inline]
39    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
40        f.write_str(self.describe())
41    }
42}
43
44/// Operation was performed and overflowed or underflowed.
45#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
46pub struct Overflowed;
47impl Fail for Overflowed {}
48impl Error for Overflowed {
49    #[inline]
50    fn describe(self) -> &'static str {
51        "operation overflowed"
52    }
53}
54impl fmt::Display for Overflowed {
55    #[inline]
56    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
57        f.write_str(self.describe())
58    }
59}
60
61/// Operation was not performed, as it would result in overflow or underflow.
62#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
63pub struct WouldOverflow;
64impl Fail for WouldOverflow {}
65impl Error for WouldOverflow {
66    fn describe(self) -> &'static str {
67        "operation was not performed, as it would overflow"
68    }
69}
70impl fmt::Display for WouldOverflow {
71    #[inline]
72    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
73        f.write_str(self.describe())
74    }
75}
76
77/// Either [`DivByZero`] or [`Overflowed`].
78#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
79pub enum DivWarning {
80    /// [`DivByZero`]
81    ByZero,
82
83    /// [`Overflowed`]
84    Overflowed,
85}
86impl Fail for DivWarning {
87    fn cause(&self) -> Option<&Fail> {
88        match *self {
89            DivWarning::ByZero => Some(&DivByZero),
90            DivWarning::Overflowed => Some(&Overflowed),
91        }
92    }
93}
94impl Error for DivWarning {
95    #[inline]
96    fn describe(self) -> &'static str {
97        match self {
98            DivWarning::ByZero => DivByZero.describe(),
99            DivWarning::Overflowed => Overflowed.describe(),
100        }
101    }
102}
103impl From<DivByZero> for DivWarning {
104    #[inline]
105    fn from(_: DivByZero) -> DivWarning {
106        DivWarning::ByZero
107    }
108}
109impl From<Overflowed> for DivWarning {
110    #[inline]
111    fn from(_: Overflowed) -> DivWarning {
112        DivWarning::Overflowed
113    }
114}
115impl fmt::Display for DivWarning {
116    #[inline]
117    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
118        f.write_str(self.describe())
119    }
120}
121
122
123/// Either [`DivByZero`] or [`WouldOverflow`].
124#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
125pub enum CannotDiv {
126    /// [`DivByZero`]
127    ByZero,
128
129    /// [`WouldOverflow`]
130    WouldOverflow,
131}
132impl Fail for CannotDiv {
133    fn cause(&self) -> Option<&Fail> {
134        match *self {
135            CannotDiv::ByZero => Some(&DivByZero),
136            CannotDiv::WouldOverflow => Some(&WouldOverflow),
137        }
138    }
139}
140impl Error for CannotDiv {
141    #[inline]
142    fn describe(self) -> &'static str {
143        match self {
144            CannotDiv::ByZero => DivByZero.describe(),
145            CannotDiv::WouldOverflow => WouldOverflow.describe(),
146        }
147    }
148}
149impl From<DivByZero> for CannotDiv {
150    #[inline]
151    fn from(_: DivByZero) -> CannotDiv {
152        CannotDiv::ByZero
153    }
154}
155impl From<WouldOverflow> for CannotDiv {
156    #[inline]
157    fn from(_: WouldOverflow) -> CannotDiv {
158        CannotDiv::WouldOverflow
159    }
160}
161impl fmt::Display for CannotDiv {
162    #[inline]
163    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
164        f.write_str(self.describe())
165    }
166}