Skip to main content

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 { &mut self.local }
24    pub fn mproto_db(&self) -> &mproto_codegen::Database { &self.mproto_db }
25    pub fn mproto_db_mut(&mut self) -> &mut mproto_codegen::Database { &mut self.mproto_db }
26
27    pub fn add_module(&mut self, name: String, module: Module) {
28        self.imports.insert(name, module);
29    }
30
31    pub fn lookup_interface<'a>(&'a self, identifier: &QualifiedIdentifier) -> Option<&'a Interface> {
32        if let Some(ref module_name) = identifier.module {
33            // Importing from another module.
34            let module = self.imports.get(module_name)?;
35            module.interface_by_name(&identifier.name)
36        } else {
37            // It's a local definition.
38            self.local.interface_by_name(&identifier.name)
39        }
40    }
41}
42
43#[derive(Debug)]
44pub struct Module {
45    interfaces: Vec<Interface>,
46    interfaces_by_name: HashMap<String, InterfaceDefId>,
47}
48
49impl Module {
50    pub fn new() -> Self {
51        Self {
52            interfaces: Vec::new(),
53            interfaces_by_name: HashMap::new(),
54        }
55    }
56
57    pub fn add_interface(&mut self, interface: Interface) -> InterfaceDefId {
58        let id = InterfaceDefId(self.interfaces.len());
59
60        self.interfaces_by_name.insert(interface.name.clone(), id);
61        self.interfaces.push(interface);
62
63        id
64    }
65
66    pub fn interface(&self, id: InterfaceDefId) -> &Interface {
67        &self.interfaces[id.0]
68    }
69
70    pub fn interface_by_name<'a>(&'a self, name: &str) -> Option<&'a Interface> {
71        let id = self.interfaces_by_name.get(name)?;
72        Some(self.interface(*id))
73    }
74}
75