Skip to main content

trs_dataframe/
error.rs

1use smartstring::alias::String as SString;
2use thiserror::Error as ThisError;
3
4use crate::Key;
5
6/// Errors produced by dataframe operations.
7#[derive(Debug, ThisError)]
8pub enum Error {
9    #[error("Empty dataset")]
10    EmptyData,
11    #[error("Dataset size doesn't match expected: {0}, get: {1}")]
12    DataSetSizeDoesntMatch(usize, usize),
13    #[error("Dataset size doesn't match idx: {0}, size of data: {1}")]
14    IndexOutOfRange(usize, usize),
15    #[error("Indexes are out of order expected: {0:?}, get: {1:?}")]
16    IndexOutOfOrder(Vec<Key>, Vec<Key>),
17    #[error("Cannot find candidate: {0}")]
18    Candidate(SString),
19    #[error("Cannot find key: {0}")]
20    NotFound(Key),
21    #[error("Column already exists: {0}")]
22    ColumnAlreadyExists(Key),
23    #[error("Cannot broadcast data")]
24    CannotBroadcast,
25    #[error("Cannot find feature: {0}")]
26    FeatureSearch(SString),
27    #[error("Invalid operation for feature: {operation} with features: {features:?}")]
28    InvalidOperation {
29        operation: SString,
30        features: Vec<SString>,
31    },
32    #[error("Unknown error: {0}")]
33    UnknownError(String),
34    #[error("IOError {0}")]
35    IOError(#[from] std::io::Error),
36    #[cfg(feature = "python")]
37    #[error("PyO3 error: {0}")]
38    PyO3(#[from] pyo3::prelude::PyErr),
39    #[error("{0}")]
40    Shape(#[from] ndarray::ShapeError),
41    #[error("Cannot find feature: {0}")]
42    MissingField(SString),
43    #[cfg(feature = "polars-df")]
44    #[error("Polars error {0}")]
45    Polars(#[from] polars::error::PolarsError),
46
47    #[error("Filter expression: {0}")]
48    Filter(#[from] crate::filter::error::Error),
49    #[error("Cast to type failed {0:?}")]
50    CastFailed(Vec<(Key, String)>),
51    #[error("DataType mismatch {0:?}")]
52    DataTypeMismatch(String),
53}
54
55impl PartialEq for Error {
56    fn eq(&self, other: &Self) -> bool {
57        match (self, other) {
58            (Self::EmptyData, Self::EmptyData) => true,
59            (Self::NotFound(a), Self::NotFound(b)) => a == b,
60            (Self::DataSetSizeDoesntMatch(a, b), Self::DataSetSizeDoesntMatch(c, d)) => {
61                a == c && b == d
62            }
63            (Self::IndexOutOfRange(a, b), Self::IndexOutOfRange(c, d)) => a == c && b == d,
64            (Self::IndexOutOfOrder(a, b), Self::IndexOutOfOrder(c, d)) => a == c && b == d,
65            (Self::Candidate(a), Self::Candidate(b)) => a == b,
66            (Self::FeatureSearch(a), Self::FeatureSearch(b)) => a == b,
67            (Self::MissingField(a), Self::MissingField(b)) => a == b,
68            (Self::UnknownError(a), Self::UnknownError(b)) => a == b,
69            (
70                Self::InvalidOperation {
71                    operation: a,
72                    features: b,
73                },
74                Self::InvalidOperation {
75                    operation: c,
76                    features: d,
77                },
78            ) => a == c && b == d,
79            (Self::IOError(a), Self::IOError(b)) => a.kind() == b.kind(),
80            (Self::ColumnAlreadyExists(a), Self::ColumnAlreadyExists(b)) => a == b,
81            (Self::CannotBroadcast, Self::CannotBroadcast) => true,
82            #[cfg(feature = "python")]
83            (Self::PyO3(a), Self::PyO3(b)) => a.to_string() == b.to_string(),
84            #[cfg(feature = "polars-df")]
85            (Self::Polars(a), Self::Polars(b)) => a.to_string() == b.to_string(),
86            _ => false,
87        }
88    }
89}
90
91#[cfg(test)]
92mod test {
93    #[cfg(feature = "python")]
94    use pyo3::{exceptions::PyValueError, PyErr};
95
96    use super::*;
97    #[test]
98    fn test_error() {
99        let err1 = Error::EmptyData;
100        assert_eq!(err1, Error::EmptyData);
101        let err = Error::DataSetSizeDoesntMatch(1, 2);
102        assert_eq!(err, Error::DataSetSizeDoesntMatch(1, 2));
103        assert_ne!(err1, err);
104        let err = Error::IndexOutOfRange(1, 2);
105        assert_eq!(err, Error::IndexOutOfRange(1, 2));
106        let err = Error::Candidate("test".into());
107        assert_eq!(err, Error::Candidate("test".into()));
108        let err = Error::FeatureSearch("test".into());
109        assert_eq!(err, Error::FeatureSearch("test".into()));
110        let err = Error::UnknownError("test".into());
111        assert_eq!(err, Error::UnknownError("test".into()));
112        let err = Error::MissingField("test".into());
113        assert_eq!(err, Error::MissingField("test".into()));
114        assert_eq!(
115            Error::NotFound("test".into()),
116            Error::NotFound("test".into())
117        );
118        assert_eq!(Error::CannotBroadcast, Error::CannotBroadcast);
119        assert_eq!(
120            Error::ColumnAlreadyExists("test".into()),
121            Error::ColumnAlreadyExists("test".into())
122        );
123        assert_eq!(
124            Error::IndexOutOfOrder(vec!["test".into()], vec!["test".into()]),
125            Error::IndexOutOfOrder(vec!["test".into()], vec!["test".into()])
126        );
127        let err = Error::IOError(std::io::Error::new(std::io::ErrorKind::Other, "test"));
128        assert_eq!(
129            err,
130            Error::IOError(std::io::Error::new(std::io::ErrorKind::Other, "test"))
131        );
132        let err = Error::InvalidOperation {
133            operation: "test".into(),
134            features: vec!["test".into()],
135        };
136        assert_eq!(
137            err,
138            Error::InvalidOperation {
139                operation: "test".into(),
140                features: vec!["test".into()],
141            }
142        );
143        #[cfg(feature = "python")]
144        {
145            let err = Error::PyO3(PyErr::new::<PyValueError, _>("foo"));
146            assert_eq!(err, Error::PyO3(PyErr::new::<PyValueError, _>("foo")));
147        }
148        #[cfg(feature = "polars-df")]
149        {
150            let err = Error::Polars(polars::error::PolarsError::ColumnNotFound("e".into()));
151            assert_eq!(
152                err,
153                Error::Polars(polars::error::PolarsError::ColumnNotFound("e".into()))
154            );
155        }
156    }
157}