Skip to main content

ironsbe_schema/
error.rs

1//! Error types for schema parsing and validation.
2
3use thiserror::Error;
4
5/// Error type for schema parsing operations.
6#[derive(Debug, Error)]
7pub enum ParseError {
8    /// XML parsing error.
9    #[error("XML parsing error: {0}")]
10    Xml(#[from] quick_xml::Error),
11
12    /// Missing required attribute.
13    #[error("missing required attribute '{attribute}' on element '{element}'")]
14    MissingAttribute {
15        /// Element name.
16        element: String,
17        /// Attribute name.
18        attribute: String,
19    },
20
21    /// Invalid attribute value.
22    #[error("invalid value '{value}' for attribute '{attribute}' on element '{element}'")]
23    InvalidAttribute {
24        /// Element name.
25        element: String,
26        /// Attribute name.
27        attribute: String,
28        /// Invalid value.
29        value: String,
30    },
31
32    /// Unknown element encountered.
33    #[error("unknown element '{element}' in context '{context}'")]
34    UnknownElement {
35        /// Element name.
36        element: String,
37        /// Parent context.
38        context: String,
39    },
40
41    /// Unknown type reference.
42    #[error("unknown type '{type_name}' referenced in field '{field}'")]
43    UnknownType {
44        /// Type name.
45        type_name: String,
46        /// Field name.
47        field: String,
48    },
49
50    /// Duplicate definition.
51    #[error("duplicate {kind} definition: '{name}'")]
52    DuplicateDefinition {
53        /// Kind of definition (type, message, etc.).
54        kind: String,
55        /// Name of the duplicate.
56        name: String,
57    },
58
59    /// Invalid schema structure.
60    #[error("invalid schema structure: {message}")]
61    InvalidStructure {
62        /// Error message.
63        message: String,
64    },
65
66    /// IO error.
67    #[error("IO error: {0}")]
68    Io(#[from] std::io::Error),
69
70    /// UTF-8 decoding error.
71    #[error("UTF-8 error: {0}")]
72    Utf8(#[from] std::str::Utf8Error),
73}
74
75/// Error type for schema validation.
76#[derive(Debug, Error)]
77pub enum SchemaError {
78    /// Parsing error.
79    #[error("parse error: {0}")]
80    Parse(#[from] ParseError),
81
82    /// Type not found.
83    #[error("type '{name}' not found")]
84    TypeNotFound {
85        /// Type name.
86        name: String,
87    },
88
89    /// Message not found.
90    #[error("message '{name}' not found")]
91    MessageNotFound {
92        /// Message name.
93        name: String,
94    },
95
96    /// Invalid field offset.
97    #[error(
98        "invalid field offset: field '{field}' at offset {offset} overlaps with previous field"
99    )]
100    InvalidOffset {
101        /// Field name.
102        field: String,
103        /// Invalid offset.
104        offset: usize,
105    },
106
107    /// Block length mismatch.
108    #[error(
109        "block length mismatch for message '{message}': declared {declared}, calculated {calculated}"
110    )]
111    BlockLengthMismatch {
112        /// Message name.
113        message: String,
114        /// Declared block length.
115        declared: u16,
116        /// Calculated block length.
117        calculated: u16,
118    },
119
120    /// Circular type reference.
121    #[error("circular type reference detected: {path}")]
122    CircularReference {
123        /// Path of the circular reference.
124        path: String,
125    },
126
127    /// Invalid enum value.
128    #[error("invalid enum value '{value}' for enum '{enum_name}'")]
129    InvalidEnumValue {
130        /// Enum name.
131        enum_name: String,
132        /// Invalid value.
133        value: String,
134    },
135
136    /// Validation error.
137    #[error("validation error: {message}")]
138    Validation {
139        /// Error message.
140        message: String,
141    },
142}
143
144impl ParseError {
145    /// Creates a missing attribute error.
146    pub fn missing_attr(element: impl Into<String>, attribute: impl Into<String>) -> Self {
147        Self::MissingAttribute {
148            element: element.into(),
149            attribute: attribute.into(),
150        }
151    }
152
153    /// Creates an invalid attribute error.
154    pub fn invalid_attr(
155        element: impl Into<String>,
156        attribute: impl Into<String>,
157        value: impl Into<String>,
158    ) -> Self {
159        Self::InvalidAttribute {
160            element: element.into(),
161            attribute: attribute.into(),
162            value: value.into(),
163        }
164    }
165
166    /// Creates an unknown element error.
167    pub fn unknown_element(element: impl Into<String>, context: impl Into<String>) -> Self {
168        Self::UnknownElement {
169            element: element.into(),
170            context: context.into(),
171        }
172    }
173
174    /// Creates a duplicate definition error.
175    pub fn duplicate(kind: impl Into<String>, name: impl Into<String>) -> Self {
176        Self::DuplicateDefinition {
177            kind: kind.into(),
178            name: name.into(),
179        }
180    }
181}