fionn_core/
error.rs

1// SPDX-License-Identifier: MIT OR Apache-2.0
2//! Error types for fionn operations
3
4use thiserror::Error;
5
6/// Errors that can occur during DSON processing
7#[derive(Error, Debug)]
8pub enum DsonError {
9    /// JSON parsing error
10    #[error("JSON parse error: {0}")]
11    ParseError(String),
12
13    /// I/O error
14    #[error("I/O error: {0}")]
15    IoError(#[from] std::io::Error),
16
17    /// Invalid field access
18    #[error("Invalid field access: {0}")]
19    InvalidField(String),
20
21    /// Schema validation error
22    #[error("Schema validation error: {0}")]
23    SchemaError(String),
24
25    /// CRDT merge conflict
26    #[error("CRDT merge conflict: {0}")]
27    MergeConflict(String),
28
29    /// Invalid operation
30    #[error("Invalid operation: {0}")]
31    InvalidOperation(String),
32
33    /// Serde serialization/deserialization error
34    #[error("Serde error: {0}")]
35    SerdeError(String),
36
37    /// JSON serialization error
38    #[error("Serialization error: {0}")]
39    SerializationError(String),
40
41    /// SIMD-JSONL processing error
42    #[error("SIMD-JSONL error: {0}")]
43    SimdJsonlError(String),
44
45    /// Skip tape processing error
46    #[error("Skip tape error: {0}")]
47    SkipTapeError(String),
48
49    /// Memory allocation error
50    #[error("Memory error: {0}")]
51    MemoryError(String),
52
53    /// Validation error
54    #[error("Validation error: {0}")]
55    ValidationError(String),
56}
57
58/// Result type alias for DSON operations
59pub type Result<T> = std::result::Result<T, DsonError>;
60
61impl From<DsonError> for String {
62    fn from(error: DsonError) -> Self {
63        error.to_string()
64    }
65}
66
67#[cfg(test)]
68mod tests {
69    use super::*;
70
71    #[test]
72    fn test_parse_error() {
73        let error = DsonError::ParseError("test".to_string());
74        assert!(error.to_string().contains("test"));
75    }
76
77    #[test]
78    fn test_invalid_field() {
79        let error = DsonError::InvalidField("field".to_string());
80        assert!(error.to_string().contains("field"));
81    }
82
83    #[test]
84    fn test_schema_error() {
85        let error = DsonError::SchemaError("schema".to_string());
86        assert!(error.to_string().contains("schema"));
87    }
88
89    #[test]
90    fn test_merge_conflict() {
91        let error = DsonError::MergeConflict("conflict".to_string());
92        assert!(error.to_string().contains("conflict"));
93    }
94
95    #[test]
96    fn test_invalid_operation() {
97        let error = DsonError::InvalidOperation("op".to_string());
98        assert!(error.to_string().contains("op"));
99    }
100
101    #[test]
102    fn test_serde_error() {
103        let error = DsonError::SerdeError("serde".to_string());
104        assert!(error.to_string().contains("serde"));
105    }
106
107    #[test]
108    fn test_serialization_error() {
109        let error = DsonError::SerializationError("ser".to_string());
110        assert!(error.to_string().contains("ser"));
111    }
112
113    #[test]
114    fn test_simd_jsonl_error() {
115        let error = DsonError::SimdJsonlError("simd".to_string());
116        assert!(error.to_string().contains("simd"));
117    }
118
119    #[test]
120    fn test_error_to_string_conversion() {
121        let error = DsonError::ParseError("test".to_string());
122        let s: String = error.into();
123        assert!(s.contains("test"));
124    }
125
126    #[test]
127    fn test_from_io_error() {
128        let io_error = std::io::Error::new(std::io::ErrorKind::NotFound, "file not found");
129        let dson_error: DsonError = io_error.into();
130        assert!(matches!(dson_error, DsonError::IoError(_)));
131        assert!(dson_error.to_string().contains("I/O error"));
132    }
133
134    #[test]
135    fn test_skiptape_error_variant() {
136        let error = DsonError::SkipTapeError("skip".to_string());
137        assert!(error.to_string().contains("skip"));
138    }
139
140    #[test]
141    fn test_memory_error_variant() {
142        let error = DsonError::MemoryError("mem".to_string());
143        assert!(error.to_string().contains("mem"));
144    }
145
146    #[test]
147    fn test_validation_error_variant() {
148        let error = DsonError::ValidationError("val".to_string());
149        assert!(error.to_string().contains("val"));
150    }
151
152    #[test]
153    fn test_io_error_display() {
154        let io_error = std::io::Error::new(std::io::ErrorKind::PermissionDenied, "access denied");
155        let dson_error: DsonError = io_error.into();
156        let s = dson_error.to_string();
157        assert!(s.contains("access denied") || s.contains("I/O"));
158    }
159
160    #[test]
161    fn test_all_error_variants_debug() {
162        let errors: Vec<DsonError> = vec![
163            DsonError::ParseError("p".to_string()),
164            DsonError::InvalidField("f".to_string()),
165            DsonError::SchemaError("s".to_string()),
166            DsonError::MergeConflict("m".to_string()),
167            DsonError::InvalidOperation("o".to_string()),
168            DsonError::SerdeError("d".to_string()),
169            DsonError::SerializationError("r".to_string()),
170            DsonError::SimdJsonlError("j".to_string()),
171            DsonError::SkipTapeError("k".to_string()),
172            DsonError::MemoryError("m".to_string()),
173            DsonError::ValidationError("v".to_string()),
174        ];
175        for error in errors {
176            let debug = format!("{error:?}");
177            assert!(!debug.is_empty());
178        }
179    }
180}