1#[derive(Debug, Clone, PartialEq, Eq)]
13pub struct OpyError {
14 pub code: String,
16 pub message: String,
18 pub span: Option<Span>,
20}
21
22#[derive(Debug, Clone, Copy, PartialEq, Eq)]
24pub struct Span {
25 pub file: u32,
26 pub start: Position,
27 pub end: Position,
28}
29
30#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, serde::Serialize)]
32pub struct Position {
33 pub line: u32,
34 pub col: u32,
35}
36
37impl Position {
38 pub const fn new(line: u32, col: u32) -> Position {
39 Position { line, col }
40 }
41}
42
43pub(crate) fn shift_position(position: Position, origin: Position) -> Position {
44 Position::new(
45 origin.line + position.line.saturating_sub(1),
46 if position.line == 1 {
47 origin.col + position.col.saturating_sub(1)
48 } else {
49 position.col
50 },
51 )
52}
53
54impl Span {
55 pub fn new(file: u32, start: Position, end: Position) -> Span {
56 Span { file, start, end }
57 }
58}
59
60pub type OpyResult<T> = Result<T, OpyError>;
62
63impl OpyError {
64 pub fn new(code: impl Into<String>, message: impl Into<String>) -> OpyError {
66 OpyError {
67 code: code.into(),
68 message: message.into(),
69 span: None,
70 }
71 }
72
73 pub fn at(code: impl Into<String>, message: impl Into<String>, span: Span) -> OpyError {
75 OpyError {
76 code: code.into(),
77 message: message.into(),
78 span: Some(span),
79 }
80 }
81}
82
83impl std::fmt::Display for OpyError {
84 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
85 write!(f, "{}: {}", self.code, self.message)
86 }
87}
88
89impl std::error::Error for OpyError {}