1use thiserror::Error;
8
9pub type Result<T> = std::result::Result<T, JsGenError>;
11
12#[derive(Debug, Error)]
17pub enum JsGenError {
18 #[error("Invalid identifier '{name}': {reason}")]
20 InvalidIdentifier {
21 name: String,
23 reason: String,
25 },
26
27 #[error("Invalid string literal: {0}")]
29 InvalidString(String),
30
31 #[error("Code generation failed: {0}")]
33 GenerationError(String),
34
35 #[error("Validation failed: {message}")]
37 ValidationError {
38 message: String,
40 location: Option<CodeLocation>,
42 },
43
44 #[error("Manifest verification failed for '{path}': {reason}")]
46 ManifestError {
47 path: String,
49 reason: String,
51 },
52
53 #[error("Hash mismatch for '{path}': expected {expected}, got {actual}")]
55 HashMismatch {
56 path: String,
58 expected: String,
60 actual: String,
62 },
63
64 #[error("IO error: {0}")]
66 Io(#[from] std::io::Error),
67
68 #[error("JSON error: {0}")]
70 Json(#[from] serde_json::Error),
71}
72
73#[derive(Debug, Clone, PartialEq, Eq)]
75pub struct CodeLocation {
76 pub line: usize,
78 pub column: usize,
80}
81
82impl std::fmt::Display for CodeLocation {
83 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
84 write!(f, "line {}, column {}", self.line, self.column)
85 }
86}
87
88#[cfg(test)]
89mod tests {
90 use super::*;
91
92 #[test]
93 fn error_display_invalid_identifier() {
94 let err = JsGenError::InvalidIdentifier {
95 name: "class".to_string(),
96 reason: "reserved word".to_string(),
97 };
98 assert_eq!(err.to_string(), "Invalid identifier 'class': reserved word");
99 }
100
101 #[test]
102 fn error_display_hash_mismatch() {
103 let err = JsGenError::HashMismatch {
104 path: "worker.js".to_string(),
105 expected: "abc123".to_string(),
106 actual: "def456".to_string(),
107 };
108 assert!(err.to_string().contains("Hash mismatch"));
109 assert!(err.to_string().contains("worker.js"));
110 }
111
112 #[test]
113 fn code_location_display() {
114 let loc = CodeLocation {
115 line: 42,
116 column: 10,
117 };
118 assert_eq!(loc.to_string(), "line 42, column 10");
119 }
120}