stack_vm/
write_once_table.rs1use crate::table::Table;
4use std::collections::HashMap;
5
6#[derive(Debug, Default)]
30pub struct WriteOnceTable<T>(HashMap<String, T>);
31
32impl<T> WriteOnceTable<T> {
33 pub fn new() -> WriteOnceTable<T> {
35 WriteOnceTable(HashMap::new())
36 }
37
38 fn already_exists_guard(&self, name: &str) {
39 if self.0.contains_key(name) {
40 panic!("Error: redefining constant {} not allowed.", name);
41 }
42 }
43
44 pub fn keys(&self) -> Vec<String> {
45 let mut result = vec![];
46 self.0.keys().for_each(|ref k| result.push(k.to_string()));
47 result
48 }
49}
50
51impl<T> Table for WriteOnceTable<T> {
52 type Item = T;
53
54 fn insert(&mut self, name: &str, value: T) {
55 self.already_exists_guard(name);
56 let name = String::from(name);
57 self.0.insert(name, value);
58 }
59
60 fn is_empty(&self) -> bool {
61 self.0.is_empty()
62 }
63
64 fn contains_key(&self, name: &str) -> bool {
65 self.0.contains_key(name)
66 }
67
68 fn get(&self, name: &str) -> Option<&T> {
69 self.0.get(name)
70 }
71}
72
73#[cfg(test)]
74mod test {
75 use super::*;
76 use crate::table::Table;
77
78 #[test]
79 fn new() {
80 let write_once_table: WriteOnceTable<usize> = WriteOnceTable::new();
81 assert!(write_once_table.is_empty())
82 }
83
84 #[test]
85 fn insert() {
86 let mut write_once_table: WriteOnceTable<usize> = WriteOnceTable::new();
87 write_once_table.insert("example", 13);
88 assert!(!write_once_table.is_empty());
89 assert_eq!(*write_once_table.get("example").unwrap(), 13);
90 }
91
92 #[test]
93 #[should_panic(expected = "redefining constant")]
94 fn insert_uniq() {
95 let mut write_once_table: WriteOnceTable<usize> = WriteOnceTable::new();
96 write_once_table.insert("example", 13);
97 assert_eq!(*write_once_table.get("example").unwrap(), 13);
98 write_once_table.insert("example", 13);
99 }
100}