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