Skip to main content

tattle/
reporter.rs

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}