trs_dataframe/
error.rs

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