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