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