Skip to main content

spq_core/ty/
reg.rs

1use fnv::FnvHashMap as HashMap;
2
3use crate::{
4    error::{anyhow, Result},
5    ty::Type,
6};
7
8type TypeId = u32;
9
10#[derive(Default)]
11pub struct TypeRegistry {
12    ty_map: HashMap<TypeId, Type>,
13}
14impl TypeRegistry {
15    /// Allocate a type handle referred by `ty_id` and optionally assign a type
16    /// to it.
17    pub fn set(&mut self, id: TypeId, ty: Type) -> Result<()> {
18        use std::collections::hash_map::Entry;
19        match self.ty_map.entry(id) {
20            Entry::Vacant(entry) => {
21                entry.insert(ty);
22                Ok(())
23            }
24            Entry::Occupied(mut entry) => {
25                if entry.get().is_device_address() && ty.is_device_pointer() {
26                    entry.insert(ty);
27                    Ok(())
28                } else {
29                    Err(anyhow!(
30                        "type collision at id {}: {:?} vs {:?}",
31                        id,
32                        entry.get(),
33                        ty
34                    ))
35                }
36            }
37        }
38    }
39
40    /// Get the type identified by `handle`.
41    pub fn get(&self, id: TypeId) -> Result<&Type> {
42        self.ty_map
43            .get(&id)
44            .ok_or(anyhow!("missing type id {}", id))
45    }
46
47    pub fn iter(&self) -> impl Iterator<Item = (&TypeId, &Type)> {
48        self.ty_map.iter()
49    }
50}