1use std::{error, fmt, io, result};
2
3#[derive(Debug)]
5#[non_exhaustive]
6pub enum ErrorKind {
7 Io(io::Error),
9
10 UnequalLengths {
13 expected_len: usize,
15 len: usize,
17 pos: Option<(u64, u64)>,
19 },
20
21 OutOfBounds {
24 pos: u64,
26 start: u64,
28 end: u64,
30 },
31}
32
33#[derive(Debug)]
35pub struct Error(ErrorKind);
36
37impl Error {
38 pub(crate) fn new(kind: ErrorKind) -> Self {
39 Self(kind)
40 }
41
42 pub fn is_io_error(&self) -> bool {
44 matches!(self.0, ErrorKind::Io(_))
45 }
46
47 pub fn kind(&self) -> &ErrorKind {
49 &self.0
50 }
51
52 pub fn into_kind(self) -> ErrorKind {
54 self.0
55 }
56}
57
58impl From<io::Error> for Error {
59 fn from(err: io::Error) -> Self {
60 Self(ErrorKind::Io(err))
61 }
62}
63
64impl From<Error> for io::Error {
65 fn from(err: Error) -> Self {
66 Self::new(io::ErrorKind::Other, err)
67 }
68}
69
70impl error::Error for Error {}
71
72impl fmt::Display for Error {
73 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
74 match self.0 {
75 ErrorKind::Io(ref err) => err.fmt(f),
76 ErrorKind::UnequalLengths {
77 expected_len,
78 len,
79 pos: Some((byte, index))
80 } => write!(
81 f,
82 "CSV error: record {} (byte: {}): found record with {} fields, but the previous record has {} fields",
83 index, byte, len, expected_len
84 ),
85 ErrorKind::UnequalLengths {
86 expected_len,
87 len,
88 pos: None
89 } => write!(
90 f,
91 "CSV error: found record with {} fields, but the previous record has {} fields",
92 len, expected_len
93 ),
94 ErrorKind::OutOfBounds { pos, start, end } => {
95 write!(f, "pos {} is out of bounds (should be >= {} and < {})", pos, start, end)
96 }
97 }
98 }
99}
100
101pub type Result<T> = result::Result<T, Error>;