1use thiserror::Error;
4use serde::{Serialize, Deserialize};
5
6#[derive(Debug, Error, Clone, Serialize, Deserialize)]
8pub enum DDEXError {
9 #[error("XML parsing error: {message}")]
10 XmlError {
11 message: String,
12 location: ErrorLocation,
13 },
14
15 #[error("Validation error: {message}")]
16 ValidationError {
17 message: String,
18 field: Option<String>,
19 },
20
21 #[error("Reference error: {message}")]
22 ReferenceError {
23 message: String,
24 reference: String,
25 },
26
27 #[error("Version mismatch: expected {expected}, found {found}")]
28 VersionMismatch {
29 expected: String,
30 found: String,
31 },
32
33 #[error("IO error: {message}")]
34 IoError {
35 message: String,
36 },
37}
38
39#[derive(Debug, Clone, Serialize, Deserialize)]
41pub struct ErrorLocation {
42 pub line: usize,
43 pub column: usize,
44 pub byte_offset: Option<usize>,
45 pub path: String,
46}
47
48impl Default for ErrorLocation {
49 fn default() -> Self {
50 Self {
51 line: 0,
52 column: 0,
53 byte_offset: None,
54 path: "unknown".to_string(),
55 }
56 }
57}
58
59pub mod ffi {
61 use super::*;
62 use crate::ffi::{FFIError, FFIErrorSeverity, FFIErrorCategory, FFIErrorLocation};
63
64 impl From<DDEXError> for FFIError {
66 fn from(err: DDEXError) -> Self {
67 match err {
68 DDEXError::XmlError { message, location } => FFIError {
69 code: "XML_PARSE_ERROR".to_string(),
70 message,
71 location: Some(FFIErrorLocation {
72 line: location.line,
73 column: location.column,
74 path: location.path,
75 }),
76 severity: FFIErrorSeverity::Error,
77 hint: Some("Check XML syntax".to_string()),
78 category: FFIErrorCategory::XmlParsing,
79 },
80 DDEXError::ValidationError { message, field } => FFIError {
81 code: "VALIDATION_ERROR".to_string(),
82 message: message.clone(),
83 location: field.map(|f| FFIErrorLocation {
84 line: 0,
85 column: 0,
86 path: f,
87 }),
88 severity: FFIErrorSeverity::Error,
89 hint: Some("Check field requirements".to_string()),
90 category: FFIErrorCategory::Validation,
91 },
92 DDEXError::ReferenceError { message, reference } => FFIError {
93 code: "REFERENCE_ERROR".to_string(),
94 message,
95 location: Some(FFIErrorLocation {
96 line: 0,
97 column: 0,
98 path: reference,
99 }),
100 severity: FFIErrorSeverity::Error,
101 hint: Some("Verify reference exists".to_string()),
102 category: FFIErrorCategory::Reference,
103 },
104 DDEXError::VersionMismatch { expected, found } => FFIError {
105 code: "VERSION_MISMATCH".to_string(),
106 message: format!("Expected version {}, found {}", expected, found),
107 location: None,
108 severity: FFIErrorSeverity::Error,
109 hint: Some("Use correct DDEX version".to_string()),
110 category: FFIErrorCategory::Version,
111 },
112 DDEXError::IoError { message } => FFIError {
113 code: "IO_ERROR".to_string(),
114 message,
115 location: None,
116 severity: FFIErrorSeverity::Error,
117 hint: None,
118 category: FFIErrorCategory::Io,
119 },
120 }
121 }
122 }
123}