Skip to main content

persistent_queue/
error.rs

1use std::error::Error as StdError;
2use std::fmt;
3
4/// Error from opening a queue over a store.
5#[derive(Debug)]
6pub enum OpenError<E> {
7    /// The backend store failed.
8    Store(E),
9    /// The store was written by an unsupported on-disk format version.
10    UnsupportedVersion(u8),
11}
12
13impl<E: fmt::Display> fmt::Display for OpenError<E> {
14    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
15        match self {
16            OpenError::Store(e) => write!(f, "store error: {e}"),
17            OpenError::UnsupportedVersion(v) => {
18                write!(f, "unsupported on-disk format version: {v}")
19            }
20        }
21    }
22}
23
24impl<E: StdError + 'static> StdError for OpenError<E> {
25    fn source(&self) -> Option<&(dyn StdError + 'static)> {
26        match self {
27            OpenError::Store(e) => Some(e),
28            OpenError::UnsupportedVersion(_) => None,
29        }
30    }
31}
32
33/// Error from a blocking [`Producer::push`](crate::Producer::push).
34#[derive(Debug)]
35pub enum PushError<E> {
36    /// The queue was closed.
37    Closed,
38    /// The backend store failed.
39    Store(E),
40}
41
42impl<E: fmt::Display> fmt::Display for PushError<E> {
43    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
44        match self {
45            PushError::Closed => write!(f, "queue is closed"),
46            PushError::Store(e) => write!(f, "store error: {e}"),
47        }
48    }
49}
50
51impl<E: StdError + 'static> StdError for PushError<E> {
52    fn source(&self) -> Option<&(dyn StdError + 'static)> {
53        match self {
54            PushError::Store(e) => Some(e),
55            PushError::Closed => None,
56        }
57    }
58}
59
60/// Error from [`Producer::try_push`](crate::Producer::try_push).
61#[derive(Debug)]
62pub enum TryPushError<E> {
63    /// The queue is at capacity.
64    Full,
65    /// The queue was closed.
66    Closed,
67    /// The backend store failed.
68    Store(E),
69}
70
71impl<E: fmt::Display> fmt::Display for TryPushError<E> {
72    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
73        match self {
74            TryPushError::Full => write!(f, "queue is full"),
75            TryPushError::Closed => write!(f, "queue is closed"),
76            TryPushError::Store(e) => write!(f, "store error: {e}"),
77        }
78    }
79}
80
81impl<E: StdError + 'static> StdError for TryPushError<E> {
82    fn source(&self) -> Option<&(dyn StdError + 'static)> {
83        match self {
84            TryPushError::Store(e) => Some(e),
85            _ => None,
86        }
87    }
88}
89
90#[cfg(test)]
91mod tests {
92    use super::*;
93    use std::io;
94
95    fn store_err() -> io::Error {
96        io::Error::other("boom")
97    }
98
99    #[test]
100    fn open_error_display_and_source() {
101        assert!(
102            OpenError::Store(store_err())
103                .to_string()
104                .contains("store error")
105        );
106        let bad = OpenError::<io::Error>::UnsupportedVersion(9);
107        assert!(bad.to_string().contains("version: 9"));
108        assert!(OpenError::Store(store_err()).source().is_some());
109        assert!(bad.source().is_none());
110    }
111
112    #[test]
113    fn push_error_display_and_source() {
114        assert!(
115            PushError::<io::Error>::Closed
116                .to_string()
117                .contains("closed")
118        );
119        assert!(
120            PushError::Store(store_err())
121                .to_string()
122                .contains("store error")
123        );
124        assert!(PushError::Store(store_err()).source().is_some());
125        assert!(PushError::<io::Error>::Closed.source().is_none());
126    }
127
128    #[test]
129    fn try_push_error_display_and_source() {
130        assert!(TryPushError::<io::Error>::Full.to_string().contains("full"));
131        assert!(
132            TryPushError::<io::Error>::Closed
133                .to_string()
134                .contains("closed")
135        );
136        assert!(
137            TryPushError::Store(store_err())
138                .to_string()
139                .contains("store error")
140        );
141        assert!(TryPushError::Store(store_err()).source().is_some());
142        assert!(TryPushError::<io::Error>::Full.source().is_none());
143    }
144}