orecc_front/
codebase.rs

1use codespan_reporting::diagnostic::Diagnostic;
2use codespan_reporting::files::{Error, SimpleFile};
3use std::rc::Rc;
4
5/// Codebase. A struct that holds all your code in memory (codespan forces this)
6#[derive(Debug, Default)]
7pub struct Codebase {
8    config: codespan_reporting::term::Config,
9    files: Vec<SimpleFile<String, Rc<str>>>,
10    errors: usize,
11    warnings: usize,
12}
13
14impl Codebase {
15    /// Create a new codebase.
16    pub fn new() -> Self {
17        Self::default()
18    }
19
20    /// Add a file to the codebase, returning the handle that can be used to
21    /// refer to it again.
22    pub fn add(&mut self, name: String, source: String) -> usize {
23        let file_id = self.files.len();
24        self.files.push(SimpleFile::new(name, Rc::from(source)));
25        file_id
26    }
27
28    /// Get the file corresponding to the given id.
29    pub fn get(&self, file_id: usize) -> Result<&SimpleFile<String, Rc<str>>, Error> {
30        self.files.get(file_id).ok_or(Error::FileMissing)
31    }
32
33    /// Emit a diagnostic
34    pub fn emit(&mut self, diagnostic: Diagnostic<usize>) {
35        match diagnostic.severity {
36            codespan_reporting::diagnostic::Severity::Bug => (),
37            codespan_reporting::diagnostic::Severity::Error => self.errors += 1,
38            codespan_reporting::diagnostic::Severity::Warning => self.warnings += 1,
39            codespan_reporting::diagnostic::Severity::Note => (),
40            codespan_reporting::diagnostic::Severity::Help => (),
41        };
42        let mut writer = codespan_reporting::term::termcolor::StandardStream::stderr(
43            codespan_reporting::term::termcolor::ColorChoice::Auto,
44        );
45        codespan_reporting::term::emit(&mut writer, &self.config, self, &diagnostic)
46            .expect("internal error");
47    }
48
49    pub fn files(&self) -> &Vec<SimpleFile<String, Rc<str>>> {
50        &self.files
51    }
52
53    /// Get the number of errors emitted
54    pub fn errors(&self) -> usize {
55        self.errors
56    }
57
58    /// Get the number of warnings emitted
59    pub fn warnings(&self) -> usize {
60        self.warnings
61    }
62}
63
64impl<'a> codespan_reporting::files::Files<'a> for Codebase {
65    type FileId = usize;
66    type Name = String;
67    type Source = &'a str;
68
69    fn name(&self, file_id: usize) -> Result<String, Error> {
70        Ok(self.get(file_id)?.name().clone())
71    }
72
73    fn source(&self, file_id: usize) -> Result<&str, Error> {
74        Ok(self.get(file_id)?.source().as_ref())
75    }
76
77    fn line_index(&self, file_id: usize, byte_index: usize) -> Result<usize, Error> {
78        self.get(file_id)?.line_index((), byte_index)
79    }
80
81    fn line_range(
82        &self,
83        file_id: usize,
84        line_index: usize,
85    ) -> Result<std::ops::Range<usize>, Error> {
86        self.get(file_id)?.line_range((), line_index)
87    }
88}