1 | //! Error types used and generated by Calloop. |
2 | //! |
3 | //! This module contains error types for Calloop's operations. They are designed |
4 | //! to make it easy to deal with errors arising from Calloop's internal I/O and |
5 | //! other operations. |
6 | //! |
7 | //! There are two top-level error types: |
8 | //! |
9 | //! - [`Error`]: used by callback functions, internal operations, and some event |
10 | //! loop API calls |
11 | //! |
12 | //! - [`InsertError`]: used primarily by the [`insert_source()`] method when an |
13 | //! event source cannot be added to the loop and needs to be given back to the |
14 | //! caller |
15 | //! |
16 | //! [`insert_source()`]: crate::LoopHandle::insert_source() |
17 | |
18 | use std::fmt::{self, Debug, Formatter}; |
19 | |
20 | /// The primary error type used by Calloop covering internal errors and I/O |
21 | /// errors that arise during loop operations such as source registration or |
22 | /// event dispatching. |
23 | #[derive (Debug)] |
24 | pub enum Error { |
25 | /// When an event source is registered (or re- or un-registered) with the |
26 | /// event loop, this error variant will occur if the token Calloop uses to |
27 | /// keep track of the event source is not valid. |
28 | InvalidToken, |
29 | |
30 | /// This variant wraps a [`std::io::Error`], which might arise from |
31 | /// Calloop's internal operations. |
32 | IoError(std::io::Error), |
33 | |
34 | /// Any other unexpected error kind (most likely from a user implementation of |
35 | /// [`EventSource::process_events()`]) will be wrapped in this. |
36 | /// |
37 | /// [`EventSource::process_events()`]: crate::EventSource::process_events() |
38 | OtherError(Box<dyn std::error::Error + Sync + Send>), |
39 | } |
40 | |
41 | impl fmt::Display for Error { |
42 | #[cfg_attr (feature = "nightly_coverage" , coverage(off))] |
43 | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { |
44 | match self { |
45 | Self::InvalidToken => f.write_str(data:"invalid token provided to internal function" ), |
46 | Self::IoError(err: &Error) => write!(f, "underlying IO error: {}" , err), |
47 | Self::OtherError(err: &Box) => write!(f, "other error during loop operation: {}" , err), |
48 | } |
49 | } |
50 | } |
51 | |
52 | impl From<std::io::Error> for Error { |
53 | #[cfg_attr (feature = "nightly_coverage" , coverage(off))] |
54 | fn from(value: std::io::Error) -> Self { |
55 | Self::IoError(value) |
56 | } |
57 | } |
58 | |
59 | impl From<Box<dyn std::error::Error + Sync + Send>> for Error { |
60 | #[cfg_attr (feature = "nightly_coverage" , coverage(off))] |
61 | fn from(value: Box<dyn std::error::Error + Sync + Send>) -> Self { |
62 | Self::OtherError(value) |
63 | } |
64 | } |
65 | |
66 | impl From<Error> for std::io::Error { |
67 | /// Converts Calloop's error type into a [`std::io::Error`]. |
68 | #[cfg_attr (feature = "nightly_coverage" , coverage(off))] |
69 | fn from(err: Error) -> Self { |
70 | match err { |
71 | Error::IoError(source: Error) => source, |
72 | Error::InvalidToken => Self::new(kind:std::io::ErrorKind::InvalidInput, error:err.to_string()), |
73 | Error::OtherError(source: Box) => Self::new(kind:std::io::ErrorKind::Other, error:source), |
74 | } |
75 | } |
76 | } |
77 | |
78 | impl std::error::Error for Error { |
79 | #[cfg_attr (feature = "nightly_coverage" , coverage(off))] |
80 | fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { |
81 | match self { |
82 | Self::InvalidToken => None, |
83 | Self::IoError(err: &Error) => Some(err), |
84 | Self::OtherError(err: &Box) => Some(&**err), |
85 | } |
86 | } |
87 | } |
88 | |
89 | /// [`Result`] alias using Calloop's error type. |
90 | pub type Result<T> = core::result::Result<T, Error>; |
91 | |
92 | /// An error generated when trying to insert an event source |
93 | pub struct InsertError<T> { |
94 | /// The source that could not be inserted |
95 | pub inserted: T, |
96 | /// The generated error |
97 | pub error: Error, |
98 | } |
99 | |
100 | impl<T> Debug for InsertError<T> { |
101 | #[cfg_attr (feature = "nightly_coverage" , coverage(off))] |
102 | fn fmt(&self, formatter: &mut Formatter) -> core::result::Result<(), fmt::Error> { |
103 | write!(formatter, " {:?}" , self.error) |
104 | } |
105 | } |
106 | |
107 | impl<T> fmt::Display for InsertError<T> { |
108 | #[cfg_attr (feature = "nightly_coverage" , coverage(off))] |
109 | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { |
110 | write!(f, "error inserting event source: {}" , &self.error) |
111 | } |
112 | } |
113 | |
114 | impl<T> From<InsertError<T>> for crate::Error { |
115 | /// Converts the [`InsertError`] into Calloop's error type, throwing away |
116 | /// the contained source. |
117 | #[cfg_attr (feature = "nightly_coverage" , coverage(off))] |
118 | fn from(e: InsertError<T>) -> crate::Error { |
119 | e.error |
120 | } |
121 | } |
122 | |
123 | impl<T> std::error::Error for InsertError<T> { |
124 | #[cfg_attr (feature = "nightly_coverage" , coverage(off))] |
125 | fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { |
126 | Some(&self.error) |
127 | } |
128 | } |
129 | |