qvm_scheduler/
error.rs

1//! Error handling for the QVM scheduler
2
3use thiserror::Error;
4
5/// Result type for QVM operations
6pub type Result<T> = core::result::Result<T, QvmError>;
7
8/// Comprehensive error types for the QVM scheduler
9#[derive(Error, Debug, Clone, PartialEq)]
10pub enum QvmError {
11    /// Circuit parsing errors
12    #[error("Parse error: {message} at position {position}")]
13    ParseError { message: String, position: usize },
14
15    /// Invalid circuit structure
16    #[error("Invalid circuit: {0}")]
17    InvalidCircuit(String),
18
19    /// Topology-related errors
20    #[error("Topology error: {0}")]
21    TopologyError(String),
22
23    /// Scheduling conflicts
24    #[error("Scheduling error: {0}")]
25    SchedulingError(String),
26
27    /// Resource allocation failures
28    #[error("Resource allocation failed: {0}")]
29    AllocationError(String),
30
31    /// Composition failures
32    #[error("Circuit composition failed: {0}")]
33    CompositionError(String),
34
35    /// I/O errors (std feature only)
36    #[cfg(feature = "std")]
37    #[error("I/O error: {0}")]
38    IoError(String),
39
40    /// Invalid configuration
41    #[error("Configuration error: {0}")]
42    ConfigError(String),
43
44    /// Internal errors that shouldn't happen
45    #[error("Internal error: {0}")]
46    InternalError(String),
47}
48
49impl QvmError {
50    /// Create a parse error
51    pub fn parse_error(message: impl Into<String>, position: usize) -> Self {
52        Self::ParseError {
53            message: message.into(),
54            position,
55        }
56    }
57
58    /// Create an invalid circuit error
59    pub fn invalid_circuit(message: impl Into<String>) -> Self {
60        Self::InvalidCircuit(message.into())
61    }
62
63    /// Create a topology error
64    pub fn topology_error(message: impl Into<String>) -> Self {
65        Self::TopologyError(message.into())
66    }
67
68    /// Create a scheduling error
69    pub fn scheduling_error(message: impl Into<String>) -> Self {
70        Self::SchedulingError(message.into())
71    }
72
73    /// Create an allocation error
74    pub fn allocation_error(message: impl Into<String>) -> Self {
75        Self::AllocationError(message.into())
76    }
77
78    /// Create a composition error
79    pub fn composition_error(message: impl Into<String>) -> Self {
80        Self::CompositionError(message.into())
81    }
82
83    /// Create a configuration error
84    pub fn config_error(message: impl Into<String>) -> Self {
85        Self::ConfigError(message.into())
86    }
87
88    /// Create an internal error
89    pub fn internal_error(message: impl Into<String>) -> Self {
90        Self::InternalError(message.into())
91    }
92}
93
94#[cfg(feature = "std")]
95impl From<std::io::Error> for QvmError {
96    fn from(err: std::io::Error) -> Self {
97        Self::IoError(err.to_string())
98    }
99}
100
101impl From<serde_json::Error> for QvmError {
102    fn from(err: serde_json::Error) -> Self {
103        Self::ParseError {
104            message: err.to_string(),
105            position: 0,
106        }
107    }
108}
109
110#[cfg(test)]
111mod tests {
112    use super::*;
113
114    #[test]
115    fn test_error_creation() {
116        let err = QvmError::parse_error("Expected token", 10);
117        assert_eq!(
118            err.to_string(),
119            "Parse error: Expected token at position 10"
120        );
121    }
122
123    #[test]
124    fn test_error_chain() {
125        let err = QvmError::scheduling_error("No resources available");
126        assert!(err.to_string().contains("scheduling"));
127    }
128}