rustre_core/engine/
mod.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
mod error;
pub mod test;
mod world;

use crate::diagnostics::Diagnostic;
use ecow::EcoVec;
pub use error::*;
use std::hash::{Hash, Hasher};
use std::path::Path;
pub use world::*;

#[derive(Clone)]
pub struct Engine<'world> {
    stdlib: Source,
    diagnostics: EcoVec<Diagnostic>,
    world: &'world dyn World,
}

impl<'world> Engine<'world> {
    pub fn new(world: &'world dyn World) -> Self {
        Self {
            stdlib: Source::stdlib(),
            diagnostics: EcoVec::new(),
            world,
        }
    }
}

impl Hash for Engine<'_> {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.diagnostics.hash(state);
    }
}

#[track]
#[allow(clippy::needless_lifetimes)] // comemo::track doesn't allow implicit lifetimes
impl<'world> Engine<'world> {
    pub fn emit(&mut self, diagnostic: Diagnostic) {
        self.diagnostics.push(diagnostic);
    }

    pub fn diagnostics(&self) -> EcoVec<Diagnostic> {
        self.diagnostics.clone()
    }

    /// Returns the Lustre standard library source file
    pub fn stdlib(&self) -> Source {
        self.stdlib.clone()
    }

    /// Forwards to [`World::input_files`]
    pub fn input_files(&self) -> EcoVec<Source> {
        self.world.input_files()
    }

    /// Forwards to [`World::imported_file`]
    pub fn imported_file(&self, relative_to: &Source, path: &Path) -> Result<Source, FileError> {
        if relative_to.file().is_stdlib() {
            // Cannot import a file from the standard library
            Err(FileError::IsSpecial)
        } else {
            self.world.imported_file(relative_to, path)
        }
    }
}