1use core::fmt;
2
3#[derive(Debug)]
5pub enum ReadErrorKind {
6 UnterminatedQuote,
8 TrailingContent,
10 #[cfg(feature = "std")]
12 Io(std::io::Error),
13 InvalidUtf8,
15}
16
17impl fmt::Display for ReadErrorKind {
18 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
19 match self {
20 ReadErrorKind::UnterminatedQuote => f.write_str("unterminated quote"),
21 ReadErrorKind::TrailingContent => f.write_str("trailing content after closing quote"),
22 ReadErrorKind::InvalidUtf8 => f.write_str("invalid UTF-8 in CSV data"),
23 #[cfg(feature = "std")]
24 ReadErrorKind::Io(e) => write!(f, "I/O error: {e}"),
25 }
26 }
27}
28
29pub struct ReadError {
31 kind: ReadErrorKind,
32 pub line: usize,
34 pub column: usize,
36}
37
38impl ReadError {
39 pub(crate) fn new(kind: ReadErrorKind, line: usize, column: usize) -> Self {
40 ReadError {
41 kind,
42 line,
43 column,
44 }
45 }
46
47 pub fn kind(&self) -> &ReadErrorKind {
49 &self.kind
50 }
51}
52
53impl fmt::Display for ReadError {
54 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
55 match &self.kind {
56 ReadErrorKind::UnterminatedQuote => {
57 write!(f, "unterminated quote at line {}, column {}", self.line, self.column)
58 }
59 ReadErrorKind::TrailingContent => {
60 write!(
61 f,
62 "trailing content after closing quote at line {}, column {}",
63 self.line, self.column
64 )
65 }
66 ReadErrorKind::InvalidUtf8 => {
67 write!(f, "invalid UTF-8 at line {}", self.line)
68 }
69 #[cfg(feature = "std")]
70 ReadErrorKind::Io(e) => write!(f, "I/O error at line {}, column {}: {}", self.line, self.column, e),
71 }
72 }
73}
74
75impl fmt::Debug for ReadError {
76 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
77 write!(f, "ReadError({})", self)
78 }
79}
80
81#[cfg(feature = "std")]
82impl std::error::Error for ReadError {
83 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
84 match &self.kind {
85 ReadErrorKind::Io(e) => Some(e),
86 _ => None,
87 }
88 }
89}
90
91#[cfg(feature = "std")]
92impl From<std::io::Error> for ReadError {
93 fn from(e: std::io::Error) -> Self {
94 ReadError::new(ReadErrorKind::Io(e), 0, 0)
95 }
96}
97
98#[derive(Debug)]
100pub enum WriteError {
101 InconsistentFieldCount {
103 expected: usize,
105 found: usize,
107 row: usize,
109 },
110 #[cfg(feature = "std")]
112 Io(std::io::Error),
113}
114
115impl fmt::Display for WriteError {
116 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
117 match self {
118 WriteError::InconsistentFieldCount {
119 expected,
120 found,
121 row,
122 } => {
123 write!(f, "expected {expected} fields, found {found} fields at row {row}")
124 }
125 #[cfg(feature = "std")]
126 WriteError::Io(e) => write!(f, "I/O error: {e}"),
127 }
128 }
129}
130
131#[cfg(feature = "std")]
132impl std::error::Error for WriteError {
133 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
134 match self {
135 WriteError::Io(e) => Some(e),
136 _ => None,
137 }
138 }
139}
140
141#[cfg(feature = "std")]
142impl From<std::io::Error> for WriteError {
143 fn from(e: std::io::Error) -> Self {
144 WriteError::Io(e)
145 }
146}