modrpc_codegen/
db.rs

1use std::collections::HashMap;
2
3use crate::ast::{Interface, QualifiedIdentifier};
4
5#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
6pub struct InterfaceDefId(usize);
7
8pub struct Database {
9    imports: HashMap<String, Module>,
10    local: Module,
11    mproto_db: mproto_codegen::Database,
12}
13
14impl Database {
15    pub fn new(mproto_db: mproto_codegen::Database) -> Self {
16        Self {
17            imports: HashMap::new(),
18            local: Module::new(),
19            mproto_db,
20        }
21    }
22
23    pub fn local(&mut self) -> &mut Module {
24        &mut self.local
25    }
26    pub fn mproto_db(&self) -> &mproto_codegen::Database {
27        &self.mproto_db
28    }
29    pub fn mproto_db_mut(&mut self) -> &mut mproto_codegen::Database {
30        &mut self.mproto_db
31    }
32
33    pub fn add_module(&mut self, name: String, module: Module) {
34        self.imports.insert(name, module);
35    }
36
37    pub fn lookup_interface<'a>(
38        &'a self,
39        identifier: &QualifiedIdentifier,
40    ) -> Option<&'a Interface> {
41        if let Some(ref module_name) = identifier.module {
42            // Importing from another module.
43            let module = self.imports.get(module_name)?;
44            module.interface_by_name(&identifier.name)
45        } else {
46            // It's a local definition.
47            self.local.interface_by_name(&identifier.name)
48        }
49    }
50}
51
52#[derive(Debug)]
53pub struct Module {
54    interfaces: Vec<Interface>,
55    interfaces_by_name: HashMap<String, InterfaceDefId>,
56}
57
58impl Module {
59    pub fn new() -> Self {
60        Self {
61            interfaces: Vec::new(),
62            interfaces_by_name: HashMap::new(),
63        }
64    }
65
66    pub fn add_interface(&mut self, interface: Interface) -> InterfaceDefId {
67        let id = InterfaceDefId(self.interfaces.len());
68
69        self.interfaces_by_name.insert(interface.name.clone(), id);
70        self.interfaces.push(interface);
71
72        id
73    }
74
75    pub fn interface(&self, id: InterfaceDefId) -> &Interface {
76        &self.interfaces[id.0]
77    }
78
79    pub fn interface_by_name<'a>(&'a self, name: &str) -> Option<&'a Interface> {
80        let id = self.interfaces_by_name.get(name)?;
81        Some(self.interface(*id))
82    }
83}