simd_csv/
error.rs

1use std::{error, fmt, io, result};
2
3/// The specific type of an error.
4#[derive(Debug)]
5#[non_exhaustive]
6pub enum ErrorKind {
7    /// Wrap a [std::io::Error].
8    Io(io::Error),
9
10    /// Indicate that a non-flexible reader or writer attempted to read/write a
11    /// unaligned record having an incorrect number of fields.
12    UnequalLengths {
13        /// Expected number of fields
14        expected_len: usize,
15        /// Actual and incorrect number of fields observed
16        len: usize,
17        /// Optional position `(byte_offset, record_index)`
18        pos: Option<(u64, u64)>,
19    },
20
21    /// Indicate that a [`Seeker`](crate::Seeker) attempted to find a record in
22    /// a position that is out of bounds
23    OutOfBounds {
24        /// Desired position
25        pos: u64,
26        /// Byte offset of the first record
27        start: u64,
28        /// Byte length of the considered stream
29        end: u64,
30    },
31}
32
33/// An error occurring when reading/writing CSV data.
34#[derive(Debug)]
35pub struct Error(ErrorKind);
36
37impl Error {
38    pub(crate) fn new(kind: ErrorKind) -> Self {
39        Self(kind)
40    }
41
42    /// Return whether the wrapped error is a [`std::io::Error`].
43    pub fn is_io_error(&self) -> bool {
44        matches!(self.0, ErrorKind::Io(_))
45    }
46
47    /// Return a reference to the underlying [`ErrorKind`].
48    pub fn kind(&self) -> &ErrorKind {
49        &self.0
50    }
51
52    /// Unwraps the error into its underlying [`ErrorKind`].
53    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
101/// A type alias for `Result<T, simd_csv::Error>`.
102pub type Result<T> = result::Result<T, Error>;