1use probl_syntax::{Diagnostic, Span};
4
5#[derive(Clone, Copy, Debug, PartialEq, Eq)]
7pub enum ErrorKind {
8 Language,
10 Unsupported,
12 Limit,
14 Internal,
16}
17
18#[derive(Clone, Debug, PartialEq)]
21pub struct OpError {
22 pub message: String,
23 pub help: Option<String>,
24 pub kind: ErrorKind,
25}
26
27impl OpError {
28 pub fn new(message: impl Into<String>) -> OpError {
29 OpError {
30 message: message.into(),
31 help: None,
32 kind: ErrorKind::Language,
33 }
34 }
35
36 pub fn unsupported(message: impl Into<String>) -> OpError {
37 OpError {
38 kind: ErrorKind::Unsupported,
39 ..OpError::new(message)
40 }
41 }
42
43 pub fn limit(message: impl Into<String>) -> OpError {
44 OpError {
45 kind: ErrorKind::Limit,
46 ..OpError::new(message)
47 }
48 }
49
50 pub fn internal(message: impl Into<String>) -> OpError {
52 OpError {
53 kind: ErrorKind::Internal,
54 ..OpError::new(message)
55 }
56 .help("this is a bug in Probl; please report it with the program that caused it")
57 }
58
59 pub fn help(mut self, help: impl Into<String>) -> OpError {
60 self.help = Some(help.into());
61 self
62 }
63
64 pub fn at(self, span: Span) -> RuntimeError {
65 RuntimeError {
66 message: self.message,
67 span,
68 notes: Vec::new(),
69 help: self.help,
70 kind: self.kind,
71 }
72 }
73}
74
75pub type OpResult<T> = std::result::Result<T, OpError>;
76
77impl From<probl_number::IntError> for OpError {
78 fn from(error: probl_number::IntError) -> Self {
79 match error {
80 probl_number::IntError::TooLarge => Self::limit(error.to_string()),
81 _ => Self::new(error.to_string()),
82 }
83 }
84}
85
86#[derive(Clone, Debug, PartialEq)]
87pub struct RuntimeError {
88 pub message: String,
89 pub span: Span,
90 pub notes: Vec<String>,
91 pub help: Option<String>,
92 pub kind: ErrorKind,
93}
94
95impl RuntimeError {
96 pub fn new(span: Span, message: impl Into<String>) -> RuntimeError {
97 OpError::new(message).at(span)
98 }
99
100 pub fn limit(span: Span, message: impl Into<String>) -> RuntimeError {
101 OpError::limit(message).at(span)
102 }
103
104 pub fn with_note(mut self, note: impl Into<String>) -> RuntimeError {
105 self.notes.push(note.into());
106 self
107 }
108
109 pub fn with_help(mut self, help: impl Into<String>) -> RuntimeError {
110 self.help = Some(help.into());
111 self
112 }
113
114 pub fn to_diagnostic(&self) -> Diagnostic {
115 let mut d = Diagnostic::error(self.span, &self.message);
116 d.notes = self.notes.clone();
117 d.help = self.help.clone();
118 d
119 }
120}
121
122pub type Result<T> = std::result::Result<T, RuntimeError>;