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