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 let module = self.imports.get(module_name)?;
35 module.interface_by_name(&identifier.name)
36 } else {
37 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