Skip to main content

oak_source_map/
error.rs

1//! Error types for source map operations.
2
3/// Result type alias for source map operations.
4pub type Result<T> = std::result::Result<T, SourceMapError>;
5
6/// Error type for source map operations.
7#[derive(Debug)]
8pub enum SourceMapError {
9    /// Invalid source map version.
10    InvalidVersion(u8),
11
12    /// Missing required field.
13    MissingField(&'static str),
14
15    /// Invalid VLQ encoding.
16    InvalidVlq {
17        /// Position in the mappings string.
18        position: usize,
19        /// Error message.
20        message: String,
21    },
22
23    /// Invalid mapping.
24    InvalidMapping {
25        /// Line number.
26        line: u32,
27        /// Column number.
28        column: u32,
29        /// Error message.
30        message: String,
31    },
32
33    /// JSON parsing error.
34    JsonError(serde_json::Error),
35
36    /// IO error.
37    IoError(std::io::Error),
38
39    /// Index out of bounds.
40    IndexOutOfBounds {
41        /// The index that was out of bounds.
42        index: usize,
43        /// The length of the collection.
44        length: usize,
45    },
46
47    /// Invalid source index.
48    InvalidSourceIndex(usize),
49
50    /// Invalid name index.
51    InvalidNameIndex(usize),
52
53    /// Source map composition error.
54    CompositionError(String),
55}
56
57impl PartialEq for SourceMapError {
58    fn eq(&self, other: &Self) -> bool {
59        match (self, other) {
60            (SourceMapError::InvalidVersion(a), SourceMapError::InvalidVersion(b)) => a == b,
61            (SourceMapError::MissingField(a), SourceMapError::MissingField(b)) => a == b,
62            (SourceMapError::InvalidVlq { position: pos_a, message: msg_a }, SourceMapError::InvalidVlq { position: pos_b, message: msg_b }) => pos_a == pos_b && msg_a == msg_b,
63            (SourceMapError::InvalidMapping { line: line_a, column: col_a, message: msg_a }, SourceMapError::InvalidMapping { line: line_b, column: col_b, message: msg_b }) => line_a == line_b && col_a == col_b && msg_a == msg_b,
64            (SourceMapError::IndexOutOfBounds { index: idx_a, length: len_a }, SourceMapError::IndexOutOfBounds { index: idx_b, length: len_b }) => idx_a == idx_b && len_a == len_b,
65            (SourceMapError::InvalidSourceIndex(a), SourceMapError::InvalidSourceIndex(b)) => a == b,
66            (SourceMapError::InvalidNameIndex(a), SourceMapError::InvalidNameIndex(b)) => a == b,
67            (SourceMapError::CompositionError(a), SourceMapError::CompositionError(b)) => a == b,
68            (SourceMapError::JsonError(_), SourceMapError::JsonError(_)) => true,
69            (SourceMapError::IoError(_), SourceMapError::IoError(_)) => true,
70            _ => false,
71        }
72    }
73}
74
75impl std::fmt::Display for SourceMapError {
76    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
77        match self {
78            SourceMapError::InvalidVersion(version) => {
79                write!(f, "Invalid source map version: expected 3, got {}", version)
80            }
81            SourceMapError::MissingField(field) => {
82                write!(f, "Missing required field: {}", field)
83            }
84            SourceMapError::InvalidVlq { position, message } => {
85                write!(f, "Invalid VLQ encoding at position {}: {}", position, message)
86            }
87            SourceMapError::InvalidMapping { line, column, message } => {
88                write!(f, "Invalid mapping at line {}, column {}: {}", line, column, message)
89            }
90            SourceMapError::JsonError(err) => {
91                write!(f, "JSON parsing error: {}", err)
92            }
93            SourceMapError::IoError(err) => {
94                write!(f, "IO error: {}", err)
95            }
96            SourceMapError::IndexOutOfBounds { index, length } => {
97                write!(f, "Index out of bounds: {} >= {}", index, length)
98            }
99            SourceMapError::InvalidSourceIndex(index) => {
100                write!(f, "Invalid source index: {}", index)
101            }
102            SourceMapError::InvalidNameIndex(index) => {
103                write!(f, "Invalid name index: {}", index)
104            }
105            SourceMapError::CompositionError(message) => {
106                write!(f, "Source map composition error: {}", message)
107            }
108        }
109    }
110}
111
112impl std::error::Error for SourceMapError {
113    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
114        match self {
115            SourceMapError::JsonError(err) => Some(err),
116            SourceMapError::IoError(err) => Some(err),
117            _ => None,
118        }
119    }
120}
121
122impl From<serde_json::Error> for SourceMapError {
123    fn from(err: serde_json::Error) -> Self {
124        SourceMapError::JsonError(err)
125    }
126}
127
128impl From<std::io::Error> for SourceMapError {
129    fn from(err: std::io::Error) -> Self {
130        SourceMapError::IoError(err)
131    }
132}
133
134impl SourceMapError {
135    /// Creates a new invalid VLQ error.
136    pub fn invalid_vlq(position: usize, message: impl Into<String>) -> Self {
137        SourceMapError::InvalidVlq { position, message: message.into() }
138    }
139
140    /// Creates a new invalid mapping error.
141    pub fn invalid_mapping(line: u32, column: u32, message: impl Into<String>) -> Self {
142        SourceMapError::InvalidMapping { line, column, message: message.into() }
143    }
144
145    /// Creates a new index out of bounds error.
146    pub fn index_out_of_bounds(index: usize, length: usize) -> Self {
147        SourceMapError::IndexOutOfBounds { index, length }
148    }
149}