Skip to main content

nexcore_dataframe/
error.rs

1//! DataFrame error types.
2
3use std::fmt;
4
5/// All errors produced by nexcore-dataframe operations.
6#[derive(Debug)]
7#[non_exhaustive]
8pub enum DataFrameError {
9    /// Named column was not found in the DataFrame.
10    ColumnNotFound(String),
11
12    /// Column lengths don't match during DataFrame construction.
13    LengthMismatch { expected: usize, actual: usize },
14
15    /// Column has wrong type for the requested operation.
16    TypeMismatch {
17        column: String,
18        expected: DataType,
19        actual: DataType,
20    },
21
22    /// Operation requires a non-empty DataFrame.
23    Empty,
24
25    /// I/O error during read/write.
26    Io(std::io::Error),
27
28    /// JSON serialization/deserialization error.
29    Json(serde_json::Error),
30
31    /// Index out of bounds.
32    IndexOutOfBounds { index: usize, length: usize },
33
34    /// Join key column count mismatch between left and right tables.
35    JoinKeyMismatch {
36        left_count: usize,
37        right_count: usize,
38    },
39
40    /// General error with message.
41    Other(String),
42}
43
44use crate::DataType;
45
46impl fmt::Display for DataFrameError {
47    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
48        match self {
49            Self::ColumnNotFound(name) => write!(f, "column not found: '{name}'"),
50            Self::LengthMismatch { expected, actual } => {
51                write!(
52                    f,
53                    "column length mismatch: expected {expected}, got {actual}"
54                )
55            }
56            Self::TypeMismatch {
57                column,
58                expected,
59                actual,
60            } => write!(
61                f,
62                "type mismatch: column '{column}' is {actual:?}, expected {expected:?}"
63            ),
64            Self::Empty => write!(f, "empty dataframe"),
65            Self::Io(e) => write!(f, "io error: {e}"),
66            Self::Json(e) => write!(f, "json error: {e}"),
67            Self::IndexOutOfBounds { index, length } => {
68                write!(f, "index {index} out of bounds for length {length}")
69            }
70            Self::JoinKeyMismatch {
71                left_count,
72                right_count,
73            } => write!(
74                f,
75                "join key count mismatch: left has {left_count}, right has {right_count}"
76            ),
77            Self::Other(msg) => write!(f, "{msg}"),
78        }
79    }
80}
81
82impl std::error::Error for DataFrameError {
83    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
84        match self {
85            Self::Io(e) => Some(e),
86            Self::Json(e) => Some(e),
87            Self::ColumnNotFound(_)
88            | Self::LengthMismatch { .. }
89            | Self::TypeMismatch { .. }
90            | Self::Empty
91            | Self::IndexOutOfBounds { .. }
92            | Self::JoinKeyMismatch { .. }
93            | Self::Other(_) => None,
94        }
95    }
96}
97
98impl From<std::io::Error> for DataFrameError {
99    fn from(e: std::io::Error) -> Self {
100        Self::Io(e)
101    }
102}
103
104impl From<serde_json::Error> for DataFrameError {
105    fn from(e: serde_json::Error) -> Self {
106        Self::Json(e)
107    }
108}