diplomat_core/
environment.rs

1use crate::ast::*;
2use std::collections::BTreeMap;
3use std::ops::Index;
4
5/// The type resolution environment
6///
7/// Also contains the entire module structure
8#[derive(Default, Clone)]
9pub struct Env {
10    pub(crate) env: BTreeMap<Path, ModuleEnv>,
11}
12
13/// The type resolution environment within a specific module
14#[derive(Clone)]
15pub struct ModuleEnv {
16    pub(crate) module: BTreeMap<Ident, ModSymbol>,
17    #[cfg_attr(not(feature = "hir"), allow(unused))]
18    pub(crate) attrs: Attrs,
19}
20
21impl Env {
22    pub(crate) fn insert(&mut self, path: Path, module: ModuleEnv) {
23        self.env.insert(path, module);
24    }
25
26    /// Given a path to a module and a name, get the item, if any
27    pub fn get(&self, path: &Path, name: &str) -> Option<&ModSymbol> {
28        self.env.get(path).and_then(|m| m.module.get(name))
29    }
30
31    /// Iterate over all items in the environment
32    ///
33    /// This will occur in a stable lexically sorted order by path and then name
34    pub fn iter_items(&self) -> impl Iterator<Item = (&Path, &Ident, &ModSymbol)> + '_ {
35        self.env
36            .iter()
37            .flat_map(|(k, v)| v.module.iter().map(move |v2| (k, v2.0, v2.1)))
38    }
39
40    /// Iterate over all modules
41    ///
42    /// This will occur in a stable lexically sorted order by path
43    pub fn iter_modules(&self) -> impl Iterator<Item = (&Path, &ModuleEnv)> + '_ {
44        self.env.iter()
45    }
46}
47
48impl ModuleEnv {
49    pub(crate) fn new(attrs: Attrs) -> Self {
50        Self {
51            module: Default::default(),
52            attrs,
53        }
54    }
55    pub(crate) fn insert(&mut self, name: Ident, symbol: ModSymbol) -> Option<ModSymbol> {
56        self.module.insert(name, symbol)
57    }
58
59    /// Given an item name, fetch it
60    pub fn get(&self, name: &str) -> Option<&ModSymbol> {
61        self.module.get(name)
62    }
63
64    /// Iterate over all name-item pairs in this module
65    pub fn iter(&self) -> impl Iterator<Item = (&Ident, &ModSymbol)> + '_ {
66        self.module.iter()
67    }
68
69    /// Iterate over all names in this module
70    ///
71    /// This will occur in a stable lexically sorted order by name
72    pub fn names(&self) -> impl Iterator<Item = &Ident> + '_ {
73        self.module.keys()
74    }
75
76    /// Iterate over all items in this module
77    ///
78    /// This will occur in a stable lexically sorted order by name
79    pub fn items(&self) -> impl Iterator<Item = &ModSymbol> + '_ {
80        self.module.values()
81    }
82}
83
84impl Index<&Path> for Env {
85    type Output = ModuleEnv;
86    fn index(&self, i: &Path) -> &ModuleEnv {
87        &self.env[i]
88    }
89}
90
91impl Index<&str> for ModuleEnv {
92    type Output = ModSymbol;
93    fn index(&self, i: &str) -> &ModSymbol {
94        &self.module[i]
95    }
96}