1use std::error::Error;
2use std::fmt;
3
4use crate::row::{OwnedRowIndex, RowIndex};
5
6#[derive(Debug)]
8pub enum RowError<'i> {
9 NotFound {
11 index: RowIndex<'i>,
13 },
14 MismatchedTypes {
18 index: RowIndex<'i>,
20 rust_type: &'static str,
22 },
23 UnexpectedNull {
28 index: RowIndex<'i>,
30 },
31 Decode {
33 index: RowIndex<'i>,
35 source: Box<dyn Error + Send + Sync>,
37 },
38 Unknown {
40 index: RowIndex<'i>,
42 source: Box<dyn Error + Send + Sync>,
46 },
47}
48
49impl<'i> RowError<'i> {
50 pub fn index(&self) -> RowIndex<'i> {
52 match self {
53 RowError::NotFound { index, .. }
54 | RowError::MismatchedTypes { index, .. }
55 | RowError::UnexpectedNull { index, .. }
56 | RowError::Decode { index, .. }
57 | RowError::Unknown { index, .. } => *index,
58 }
59 }
60
61 pub fn into_owned(self) -> OwnedRowError {
63 match self {
64 RowError::NotFound { index } => OwnedRowError::NotFound {
65 index: index.into_owned(),
66 },
67 RowError::MismatchedTypes { index, rust_type } => OwnedRowError::MismatchedTypes {
68 index: index.into_owned(),
69 rust_type,
70 },
71 RowError::UnexpectedNull { index } => OwnedRowError::UnexpectedNull {
72 index: index.into_owned(),
73 },
74 RowError::Decode { index, source } => OwnedRowError::Decode {
75 index: index.into_owned(),
76 source,
77 },
78 RowError::Unknown { index, source } => OwnedRowError::Unknown {
79 index: index.into_owned(),
80 source,
81 },
82 }
83 }
84}
85
86#[derive(Debug)]
88pub enum OwnedRowError {
89 NotFound {
91 index: OwnedRowIndex,
93 },
94 MismatchedTypes {
98 index: OwnedRowIndex,
100 rust_type: &'static str,
102 },
103 UnexpectedNull {
108 index: OwnedRowIndex,
110 },
111 Decode {
113 index: OwnedRowIndex,
115 source: Box<dyn Error + Send + Sync>,
117 },
118 Unknown {
120 index: OwnedRowIndex,
122 source: Box<dyn Error + Send + Sync>,
126 },
127}
128
129impl OwnedRowError {
130 pub fn index(&self) -> &OwnedRowIndex {
132 match self {
133 OwnedRowError::NotFound { index, .. }
134 | OwnedRowError::MismatchedTypes { index, .. }
135 | OwnedRowError::UnexpectedNull { index, .. }
136 | OwnedRowError::Decode { index, .. }
137 | OwnedRowError::Unknown { index, .. } => index,
138 }
139 }
140}
141
142impl From<OwnedRowError> for crate::Error {
143 fn from(value: OwnedRowError) -> Self {
144 crate::Error::RowError(value)
145 }
146}
147
148impl<'i> From<RowError<'i>> for OwnedRowError {
149 fn from(value: RowError<'i>) -> Self {
150 value.into_owned()
151 }
152}
153
154impl<'i> From<RowError<'i>> for crate::Error {
155 fn from(value: RowError<'i>) -> Self {
156 value.into_owned().into()
157 }
158}
159
160macro_rules! impl_display {
161 (impl$(<$lifetime:lifetime>)? fmt::Display for $Enum:ty { .. }) => {
162 impl$(<$lifetime>)? fmt::Display for $Enum {
163 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
164 match self {
165 Self::NotFound { index } => write!(f, "Column {index:?} was not found"),
166 Self::MismatchedTypes { index, rust_type } => write!(f, "Column {index:?} does not match type {rust_type}"),
167 Self::UnexpectedNull { index } => write!(f, "Column {index:?} is `NULL`; try decoding as `Option`"),
168 Self::Decode { index, source } => write!(f, "Couldn't decode column {index:?}: {source}"),
169 Self::Unknown { index, source } => write!(f, "An unknown error occurred at column {index:?}: {source}"),
170 }
171 }
172 }
173 };
174}
175impl_display!(impl<'i> fmt::Display for RowError<'i> {..});
176impl_display!(impl fmt::Display for OwnedRowError {..});
177
178macro_rules! impl_error {
179 (impl$(<$lifetime:lifetime>)? Error for $Enum:ty { .. }) => {
180 impl$(<$lifetime>)? Error for $Enum {
181 fn source(&self) -> Option<&(dyn Error + 'static)> {
182 match self {
183 Self::Decode { source, .. } => Some(source.as_ref()),
184 Self::Unknown { source, .. } => Some(source.as_ref()),
185 _ => None,
186 }
187 }
188 }
189 };
190}
191impl_error!(impl<'i> Error for RowError<'i> {..});
192impl_error!(impl Error for OwnedRowError {..});