minecraftrs/
res.rs

1use std::collections::HashMap;
2use std::hash::Hash;
3use std::fmt::Display;
4
5/// Common trait for all object usable in the registry.
6pub trait Registrable<ID: Eq + Hash> {
7    fn get_name(&self) -> &'static str;
8    fn get_id(&self) -> ID;
9}
10
11
12/// A block registry, used to store all available blocks for a specific
13/// versions and get them by their identifier or legacy ids.
14pub struct Registry<ID: Eq + Hash, T: Registrable<ID>> {
15    data: Vec<T>,
16    by_names: HashMap<&'static str, usize>,
17    by_ids: HashMap<ID, usize>
18}
19
20
21impl<ID, T> Registry<ID, T>
22where
23    ID: Eq + Hash,
24    T: Registrable<ID>
25{
26
27    pub fn new() -> Self {
28        Registry {
29            data: Vec::new(),
30            by_names: HashMap::new(),
31            by_ids: HashMap::new()
32        }
33    }
34
35    pub fn register(&mut self, item: T) -> bool {
36
37        if self.by_names.contains_key(&item.get_name()) ||
38            self.by_ids.contains_key(&item.get_id()) {
39
40            false
41
42        } else {
43
44            let idx = self.data.len();
45            self.by_names.insert(item.get_name(), idx);
46            self.by_ids.insert(item.get_id(), idx);
47            self.data.push(item);
48
49            true
50
51        }
52
53    }
54
55    pub fn get_from_name(&self, name: &str) -> Option<&T> {
56        Some(&self.data[*self.by_names.get(&name)?])
57    }
58
59    pub fn get_from_id(&self, id: ID) -> Option<&T> {
60        Some(&self.data[*self.by_ids.get(&id)?])
61    }
62
63    pub fn expect_from_name(&self, name: &str) -> &T {
64        self.get_from_name(name).expect(format!("Missing name '{}' in the registry.", name).as_str())
65    }
66
67    pub fn expect_from_id(&self, id: ID) -> &T
68    where
69        ID: Display + Copy
70    {
71        self.get_from_id(id).expect(format!("Missing id '{}' in the registry.", id).as_str())
72    }
73
74    pub fn check_if_exists<'a>(&self, item: &'a T) -> &'a T {
75        if !self.by_ids.contains_key(&item.get_id()) {
76            panic!("The item '{}' is not registered.", item.get_name());
77        } else {
78            item
79        }
80    }
81
82}