|
| 1 | +use std::borrow::Cow; |
| 2 | +use std::fmt::{self, Display, Formatter}; |
1 | 3 | use std::sync::Arc; |
2 | 4 |
|
3 | | -use derive_where::derive_where; |
4 | 5 | use static_assertions::assert_impl_all; |
5 | 6 | use thiserror::Error; |
6 | 7 |
|
@@ -87,18 +88,41 @@ pub enum Error { |
87 | 88 | RuntimeInconsistent, |
88 | 89 |
|
89 | 90 | #[error(transparent)] |
90 | | - Other(OtherError), |
| 91 | + Custom(CustomError), |
91 | 92 | } |
92 | 93 |
|
93 | 94 | #[derive(Error, Clone, Debug)] |
94 | | -#[derive_where(Eq, PartialEq)] |
95 | | -#[error("{message}")] |
96 | | -pub struct OtherError { |
97 | | - message: Arc<String>, |
98 | | - #[derive_where(skip(EqHashOrd))] |
| 95 | +pub struct CustomError { |
| 96 | + message: Option<Arc<Cow<'static, str>>>, |
99 | 97 | source: Option<Arc<dyn std::error::Error + Send + Sync + 'static>>, |
100 | 98 | } |
101 | 99 |
|
| 100 | +impl Display for CustomError { |
| 101 | + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { |
| 102 | + match (self.message.as_ref(), self.source.as_ref()) { |
| 103 | + (Some(message), None) => f.write_str(message), |
| 104 | + (Some(message), Some(err)) => write!(f, "{}: {}", message, err), |
| 105 | + (None, Some(err)) => err.fmt(f), |
| 106 | + _ => unreachable!("no error message or source"), |
| 107 | + } |
| 108 | + } |
| 109 | +} |
| 110 | + |
| 111 | +impl PartialEq for CustomError { |
| 112 | + fn eq(&self, other: &Self) -> bool { |
| 113 | + if !self.message.eq(&other.message) { |
| 114 | + return false; |
| 115 | + } |
| 116 | + match (self.source.as_ref(), other.source.as_ref()) { |
| 117 | + (Some(lhs), Some(rhs)) => Arc::ptr_eq(lhs, rhs), |
| 118 | + (None, None) => true, |
| 119 | + _ => false, |
| 120 | + } |
| 121 | + } |
| 122 | +} |
| 123 | + |
| 124 | +impl Eq for CustomError {} |
| 125 | + |
102 | 126 | impl Error { |
103 | 127 | pub(crate) fn is_terminated(&self) -> bool { |
104 | 128 | matches!(self, Self::NoHosts | Self::SessionExpired | Self::AuthFailed | Self::ClientClosed) |
@@ -131,20 +155,20 @@ impl Error { |
131 | 155 | } |
132 | 156 | } |
133 | 157 |
|
134 | | - pub(crate) fn new_other( |
135 | | - message: impl Into<Arc<String>>, |
136 | | - source: Option<Arc<dyn std::error::Error + Send + Sync + 'static>>, |
137 | | - ) -> Self { |
138 | | - Self::Other(OtherError { message: message.into(), source }) |
| 158 | + pub(crate) fn with_message(message: impl Into<Cow<'static, str>>) -> Self { |
| 159 | + Self::Custom(CustomError { message: Some(Arc::new(message.into())), source: None }) |
139 | 160 | } |
140 | 161 |
|
141 | 162 | #[allow(dead_code)] |
142 | | - pub(crate) fn other(message: impl Into<String>, source: impl std::error::Error + Send + Sync + 'static) -> Self { |
143 | | - Self::new_other(message.into(), Some(Arc::new(source))) |
| 163 | + pub(crate) fn with_other( |
| 164 | + message: impl Into<Cow<'static, str>>, |
| 165 | + source: impl std::error::Error + Send + Sync + 'static, |
| 166 | + ) -> Self { |
| 167 | + Self::Custom(CustomError { message: Some(Arc::new(message.into())), source: Some(Arc::new(source)) }) |
144 | 168 | } |
145 | 169 |
|
146 | | - pub(crate) fn other_from(source: impl std::error::Error + Send + Sync + 'static) -> Self { |
147 | | - Self::new_other(source.to_string(), Some(Arc::new(source))) |
| 170 | + pub(crate) fn other(source: impl std::error::Error + Send + Sync + 'static) -> Self { |
| 171 | + Self::Custom(CustomError { message: None, source: Some(Arc::new(source)) }) |
148 | 172 | } |
149 | 173 | } |
150 | 174 |
|
|
0 commit comments