1use thiserror::Error;
4
5#[cfg(feature = "serde")]
6use serde::{Deserialize, Serialize};
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
11pub struct Span {
12 pub start: usize,
14 pub end: usize,
16}
17
18impl Span {
19 pub fn new(start: usize, end: usize) -> Self {
21 Self { start, end }
22 }
23
24 pub fn merge(self, other: Span) -> Span {
26 Span::new(self.start.min(other.start), self.end.max(other.end))
27 }
28}
29
30#[derive(Error, Debug, Clone, PartialEq)]
32pub enum CompileError {
33 #[error("lex error at {span:?}: {msg}")]
35 Lex {
36 msg: String,
38 span: Span,
40 },
41 #[error("parse error at {span:?}: {msg}")]
43 Parse {
44 msg: String,
46 span: Span,
48 },
49 #[error("type error at {span:?}: {msg}")]
51 Type {
52 msg: String,
54 span: Span,
56 },
57 #[error("unsupported: {0}")]
59 Unsupported(String),
60}
61
62#[cfg(test)]
63mod tests {
64 use super::*;
65
66 #[test]
67 fn span_merge_covers_both() {
68 let a = Span::new(2, 5);
69 let b = Span::new(8, 10);
70 assert_eq!(a.merge(b), Span::new(2, 10));
71 }
72}