1use crate::codes::ErrorCode;
2use crate::loc::Loc;
3
4use std::cell::Cell;
5use std::{cell::RefCell, rc::Rc};
6
7pub struct Error {
8 pub code: ErrorCode,
9 pub loc: Option<Loc>,
10 pub message: String,
11}
12
13impl Error {
14 fn new(code: ErrorCode, loc: Option<Loc>, message: String) -> Self {
15 Self { code, loc, message }
16 }
17}
18
19pub enum Message {
20 Error(Error),
21 Info(String),
22}
23
24#[derive(Clone)]
25pub struct Reporter {
26 log: Rc<RefCell<Vec<Message>>>,
27 errored: Rc<Cell<bool>>,
28}
29
30impl Reporter {
31 pub fn new() -> Self {
32 Self {
33 log: Rc::new(RefCell::new(Vec::new())),
34 errored: Rc::new(Cell::new(false)),
35 }
36 }
37
38 pub fn errored(&self) -> bool {
39 self.errored.get()
40 }
41
42 pub fn error(&self, loc: Loc, code: ErrorCode, message: String) {
43 self.error_option_loc(Some(loc), code, message);
44 }
45
46 pub fn error_unknown_loc(&self, code: ErrorCode, message: String) {
47 self.error_option_loc(None, code, message);
48 }
49
50 pub fn error_option_loc(&self, loc: Option<Loc>, code: ErrorCode, message: String) {
51 self.errored.set(true);
52 let e = Error::new(code, loc, message);
53 let m = Message::Error(e);
54 self.log.borrow_mut().push(m)
55 }
56
57 pub fn info(&self, message: String) {
58 let m = Message::Info(message);
59 self.log.borrow_mut().push(m);
60 }
61
62 pub fn poll(&self) -> Vec<Message> {
63 self.errored.set(false);
64 self.log.replace(Vec::new())
65 }
66}