1use core::fmt;
2
3extern crate alloc;
4#[cfg(feature = "std")]
5use alloc::boxed::Box;
6#[cfg(feature = "serde")]
7use alloc::string::String;
8
9#[derive(Clone, Debug, PartialEq)]
11pub enum ReadErrorKind {
12 UnterminatedQuote,
14 TrailingContent,
16 InvalidUtf8,
18 InconsistentFieldCount { expected: usize, found: usize },
20 #[cfg(feature = "serde")]
22 Deserialize(String),
23 Io,
25}
26
27#[derive(Debug)]
32pub struct ReadError {
33 pub kind: ReadErrorKind,
34 pub line: usize,
35 pub column: usize,
36 #[cfg(feature = "std")]
37 source: Option<Box<dyn std::error::Error + Send + Sync + 'static>>,
38}
39
40impl ReadError {
41 pub fn new(kind: ReadErrorKind, line: usize, column: usize) -> Self {
42 ReadError {
43 kind,
44 line,
45 column,
46 #[cfg(feature = "std")]
47 source: None,
48 }
49 }
50
51 pub fn kind(&self) -> &ReadErrorKind {
52 &self.kind
53 }
54
55 #[cfg(feature = "std")]
57 pub fn into_source(self) -> Option<Box<dyn std::error::Error + Send + Sync + 'static>> {
58 self.source
59 }
60}
61
62impl Clone for ReadError {
63 fn clone(&self) -> Self {
64 ReadError {
65 kind: self.kind.clone(),
66 line: self.line,
67 column: self.column,
68 #[cfg(feature = "std")]
69 source: None,
70 }
71 }
72}
73
74impl fmt::Display for ReadError {
75 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
76 match &self.kind {
77 ReadErrorKind::UnterminatedQuote => {
78 write!(f, "unterminated quote at line {}, column {}", self.line, self.column)
79 }
80 ReadErrorKind::TrailingContent => {
81 write!(
82 f,
83 "trailing content after quoted field at line {}, column {}",
84 self.line, self.column
85 )
86 }
87 ReadErrorKind::InvalidUtf8 => {
88 write!(f, "invalid UTF-8 at line {}, column {}", self.line, self.column)
89 }
90 ReadErrorKind::InconsistentFieldCount {
91 expected,
92 found,
93 } => {
94 write!(
95 f,
96 "expected {expected} fields, found {found} at line {}, column {}",
97 self.line, self.column
98 )
99 }
100 #[cfg(feature = "serde")]
101 ReadErrorKind::Deserialize(msg) => {
102 write!(f, "deserialization error at line {}, column {}: {msg}", self.line, self.column)
103 }
104 ReadErrorKind::Io => {
105 write!(f, "I/O error at line {}, column {}", self.line, self.column)
106 }
107 }
108 }
109}
110
111#[cfg(feature = "std")]
112impl std::error::Error for ReadError {
113 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
114 self.source
115 .as_ref()
116 .map(|b| b.as_ref() as &(dyn std::error::Error + 'static))
117 }
118}
119
120#[cfg(all(not(feature = "std"), feature = "serde"))]
121impl core::error::Error for ReadError {}
122
123#[cfg(feature = "std")]
124impl From<std::io::Error> for ReadError {
125 fn from(e: std::io::Error) -> Self {
126 ReadError {
127 kind: ReadErrorKind::Io,
128 line: 0,
129 column: 0,
130 source: Some(Box::new(e)),
131 }
132 }
133}
134
135#[derive(Debug)]
137pub enum WriteError {
138 InconsistentFieldCount { expected: usize, found: usize, row: usize },
140 HeadersAlreadyWritten,
142 #[cfg(feature = "serde")]
144 Serialize(String),
145 #[cfg(feature = "std")]
147 Io(std::io::Error),
148 #[cfg(not(feature = "std"))]
150 Io,
151}
152
153impl fmt::Display for WriteError {
154 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
155 match self {
156 WriteError::InconsistentFieldCount {
157 expected,
158 found,
159 row,
160 } => {
161 write!(f, "expected {expected} fields, found {found} in row {row}")
162 }
163 WriteError::HeadersAlreadyWritten => write!(f, "headers have already been written"),
164 #[cfg(feature = "serde")]
165 WriteError::Serialize(msg) => write!(f, "serialization error: {msg}"),
166 #[cfg(feature = "std")]
167 WriteError::Io(e) => write!(f, "I/O error: {e}"),
168 #[cfg(not(feature = "std"))]
169 WriteError::Io => write!(f, "I/O error"),
170 }
171 }
172}
173
174#[cfg(feature = "std")]
175impl std::error::Error for WriteError {
176 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
177 match self {
178 WriteError::Io(e) => Some(e),
179 _ => None,
180 }
181 }
182}
183
184#[cfg(not(feature = "std"))]
185impl core::error::Error for WriteError {}
186
187#[cfg(feature = "std")]
188impl From<std::io::Error> for WriteError {
189 fn from(e: std::io::Error) -> Self {
190 WriteError::Io(e)
191 }
192}