trs_dataframe/
error.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
use smartstring::alias::String as SString;
use thiserror::Error as ThisError;

use crate::Key;

#[derive(Debug, ThisError)]
pub enum Error {
    #[error("Empty dataset")]
    EmptyData,
    #[error("Dataset size doesn't match expected: {0}, get: {1}")]
    DataSetSizeDoesntMatch(usize, usize),
    #[error("Dataset size doesn't match idx: {0}, size of data: {1}")]
    IndexOutOfRange(usize, usize),
    #[error("Indexes are out of order expected: {0:?}, get: {1:?}")]
    IndexOutOfOrder(Vec<Key>, Vec<Key>),
    #[error("Cannot find candidate: {0}")]
    Candidate(SString),
    #[error("Cannot find key: {0}")]
    NotFound(Key),
    #[error("Column already exists: {0}")]
    ColumnAlreadyExists(Key),
    #[error("Cannot broadcast data")]
    CannotBroadcast,
    #[error("Cannot find feature: {0}")]
    FeatureSearch(SString),
    #[error("Invalid operation for feature: {operation} with features: {features:?}")]
    InvalidOperation {
        operation: SString,
        features: Vec<SString>,
    },
    #[error("Unknown error: {0}")]
    UnknownError(String),
    #[error("IOError {0}")]
    IOError(#[from] std::io::Error),
    #[cfg(feature = "python")]
    #[error("PyO3 error: {0}")]
    PyO3(#[from] pyo3::prelude::PyErr),
    #[error("{0}")]
    Shape(#[from] ndarray::ShapeError),
}

impl PartialEq for Error {
    fn eq(&self, other: &Self) -> bool {
        match (self, other) {
            (Self::EmptyData, Self::EmptyData) => true,
            (Self::NotFound(a), Self::NotFound(b)) => a == b,
            (Self::DataSetSizeDoesntMatch(a, b), Self::DataSetSizeDoesntMatch(c, d)) => {
                a == c && b == d
            }
            (Self::IndexOutOfRange(a, b), Self::IndexOutOfRange(c, d)) => a == c && b == d,
            (Self::IndexOutOfOrder(a, b), Self::IndexOutOfOrder(c, d)) => a == c && b == d,
            (Self::Candidate(a), Self::Candidate(b)) => a == b,
            (Self::FeatureSearch(a), Self::FeatureSearch(b)) => a == b,
            (Self::UnknownError(a), Self::UnknownError(b)) => a == b,
            (
                Self::InvalidOperation {
                    operation: a,
                    features: b,
                },
                Self::InvalidOperation {
                    operation: c,
                    features: d,
                },
            ) => a == c && b == d,
            (Self::IOError(a), Self::IOError(b)) => a.kind() == b.kind(),
            (Self::ColumnAlreadyExists(a), Self::ColumnAlreadyExists(b)) => a == b,
            (Self::CannotBroadcast, Self::CannotBroadcast) => true,
            #[cfg(feature = "python")]
            (Self::PyO3(a), Self::PyO3(b)) => a.to_string() == b.to_string(),
            _ => false,
        }
    }
}

#[cfg(test)]
mod test {
    #[cfg(feature = "python")]
    use pyo3::{exceptions::PyValueError, PyErr};

    use super::*;
    #[test]
    fn test_error() {
        let err1 = Error::EmptyData;
        assert_eq!(err1, Error::EmptyData);
        let err = Error::DataSetSizeDoesntMatch(1, 2);
        assert_eq!(err, Error::DataSetSizeDoesntMatch(1, 2));
        assert_ne!(err1, err);
        let err = Error::IndexOutOfRange(1, 2);
        assert_eq!(err, Error::IndexOutOfRange(1, 2));
        let err = Error::Candidate("test".into());
        assert_eq!(err, Error::Candidate("test".into()));
        let err = Error::FeatureSearch("test".into());
        assert_eq!(err, Error::FeatureSearch("test".into()));
        let err = Error::UnknownError("test".into());
        assert_eq!(err, Error::UnknownError("test".into()));
        assert_eq!(
            Error::NotFound("test".into()),
            Error::NotFound("test".into())
        );
        assert_eq!(Error::CannotBroadcast, Error::CannotBroadcast);
        assert_eq!(
            Error::ColumnAlreadyExists("test".into()),
            Error::ColumnAlreadyExists("test".into())
        );
        assert_eq!(
            Error::IndexOutOfOrder(vec!["test".into()], vec!["test".into()]),
            Error::IndexOutOfOrder(vec!["test".into()], vec!["test".into()])
        );
        let err = Error::IOError(std::io::Error::new(std::io::ErrorKind::Other, "test"));
        assert_eq!(
            err,
            Error::IOError(std::io::Error::new(std::io::ErrorKind::Other, "test"))
        );
        let err = Error::InvalidOperation {
            operation: "test".into(),
            features: vec!["test".into()],
        };
        assert_eq!(
            err,
            Error::InvalidOperation {
                operation: "test".into(),
                features: vec!["test".into()],
            }
        );
        #[cfg(feature = "python")]
        {
            let err = Error::PyO3(PyErr::new::<PyValueError, _>("foo"));
            assert_eq!(err, Error::PyO3(PyErr::new::<PyValueError, _>("foo")));
        }
    }
}