telltale_machine/
intern.rs1use crate::session::SessionId;
4use serde::{Deserialize, Serialize};
5use std::collections::BTreeMap;
6
7pub type StringId = u32;
9
10pub type EdgeId = u32;
12
13#[derive(Debug, Clone, Default, Serialize, Deserialize)]
15pub struct SymbolTable {
16 symbols: Vec<String>,
17 index: BTreeMap<String, StringId>,
18}
19
20impl SymbolTable {
21 #[must_use]
23 pub fn new() -> Self {
24 Self::default()
25 }
26
27 pub fn intern(&mut self, value: &str) -> StringId {
29 if let Some(id) = self.index.get(value) {
30 return *id;
31 }
32 let id = match u32::try_from(self.symbols.len()) {
33 Ok(id) => id,
34 Err(_) => return u32::MAX,
35 };
36 let owned = value.to_string();
37 self.symbols.push(owned.clone());
38 self.index.insert(owned, id);
39 id
40 }
41
42 #[must_use]
44 #[allow(clippy::as_conversions)]
45 pub fn resolve(&self, id: StringId) -> Option<&str> {
46 self.symbols.get(id as usize).map(String::as_str)
48 }
49
50 #[must_use]
52 pub fn len(&self) -> usize {
53 self.symbols.len()
54 }
55
56 #[must_use]
58 pub fn is_empty(&self) -> bool {
59 self.symbols.is_empty()
60 }
61}
62
63#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
65pub struct EdgeSymbol {
66 pub sid: SessionId,
68 pub sender: StringId,
70 pub receiver: StringId,
72}
73
74#[derive(Debug, Clone, Default, Serialize, Deserialize)]
76pub struct EdgeSymbolTable {
77 symbols: Vec<EdgeSymbol>,
78 index: BTreeMap<EdgeSymbol, EdgeId>,
79}
80
81impl EdgeSymbolTable {
82 #[must_use]
84 pub fn new() -> Self {
85 Self::default()
86 }
87
88 pub fn intern(&mut self, sid: SessionId, sender: StringId, receiver: StringId) -> EdgeId {
90 let edge = EdgeSymbol {
91 sid,
92 sender,
93 receiver,
94 };
95 if let Some(id) = self.index.get(&edge) {
96 return *id;
97 }
98 let id = match u32::try_from(self.symbols.len()) {
99 Ok(id) => id,
100 Err(_) => return u32::MAX,
101 };
102 self.symbols.push(edge);
103 self.index.insert(edge, id);
104 id
105 }
106
107 #[must_use]
109 #[allow(clippy::as_conversions)]
110 pub fn resolve(&self, id: EdgeId) -> Option<EdgeSymbol> {
111 self.symbols.get(id as usize).copied()
112 }
113
114 #[must_use]
116 pub fn len(&self) -> usize {
117 self.symbols.len()
118 }
119
120 #[must_use]
122 pub fn is_empty(&self) -> bool {
123 self.symbols.is_empty()
124 }
125}