petr_utils/
common_types.rs1use std::rc::Rc;
4
5#[cfg(feature = "debug")]
6use lazy_static::lazy_static;
7
8use crate::{idx_map_key, IndexMap};
9#[cfg(feature = "debug")]
10lazy_static! {
11 pub static ref SYMBOL_INTERNER: std::sync::RwLock<Vec<String>> = std::sync::RwLock::new(Vec::new());
12}
13
14idx_map_key!(
15 TypeId
17);
18
19#[derive(Clone, Copy, Debug, PartialEq, Eq)]
20pub struct Identifier {
21 pub id: SymbolId,
22 pub span: crate::Span,
23}
24
25impl PartialOrd for Identifier {
27 fn partial_cmp(
28 &self,
29 other: &Self,
30 ) -> Option<std::cmp::Ordering> {
31 Some(self.cmp(other))
32 }
33}
34
35impl Ord for Identifier {
36 fn cmp(
37 &self,
38 other: &Self,
39 ) -> std::cmp::Ordering {
40 self.id.cmp(&other.id)
41 }
42}
43
44impl Identifier {
45 pub fn span(&self) -> crate::Span {
46 self.span
47 }
48}
49
50#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
51pub struct Path {
52 pub identifiers: Box<[Identifier]>,
53}
54
55impl Path {
56 pub fn new(identifiers: Vec<Identifier>) -> Self {
57 Self {
58 identifiers: identifiers.into_boxed_slice(),
59 }
60 }
61}
62
63impl Path {
64 pub fn len(&self) -> usize {
65 self.identifiers.len()
66 }
67
68 pub fn is_empty(&self) -> bool {
69 self.identifiers.is_empty()
70 }
71
72 pub fn iter(&self) -> std::slice::Iter<'_, Identifier> {
73 self.identifiers.iter()
74 }
75}
76
77#[cfg(not(feature = "debug"))]
78idx_map_key!(
79 SymbolId
81);
82
83#[cfg(feature = "debug")]
84#[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd)]
85#[doc = r"The ID of an ident in the symbol interner"]
86pub struct SymbolId(usize);
87
88#[cfg(feature = "debug")]
89impl From<usize> for SymbolId {
90 fn from(value: usize) -> Self {
91 Self(value)
92 }
93}
94#[cfg(feature = "debug")]
95impl From<SymbolId> for usize {
96 fn from(o: SymbolId) -> usize {
97 o.0
98 }
99}
100#[cfg(feature = "debug")]
101impl std::fmt::Display for SymbolId {
102 fn fmt(
103 &self,
104 f: &mut std::fmt::Formatter<'_>,
105 ) -> std::fmt::Result {
106 let name = crate::SYMBOL_INTERNER.read().unwrap().get(self.0).unwrap().to_string();
107 write!(f, "{}", name)
108 }
109}
110
111#[derive(Default, Debug, Clone)]
112pub struct SymbolInterner {
113 symbol_map: IndexMap<SymbolId, Rc<str>>,
114}
115
116impl SymbolInterner {
117 pub fn get_path(
118 &self,
119 path: &Path,
120 ) -> Vec<Rc<str>> {
121 path.iter().map(|id| self.get(id.id)).collect()
122 }
123
124 #[cfg(not(feature = "debug"))]
125 pub fn insert(
126 &mut self,
127 v: Rc<str>,
128 ) -> SymbolId {
129 match self.symbol_map.contains_value(v.clone()) {
130 Some(k) => k,
131 None => self.symbol_map.insert(v),
132 }
133 }
134
135 #[cfg(feature = "debug")]
136 pub fn insert(
137 &mut self,
138 v: Rc<str>,
139 ) -> SymbolId {
140 match self.symbol_map.contains_value(v.clone()) {
141 Some(k) => k,
142 None => {
143 let id = self.symbol_map.insert(v.clone());
144 crate::SYMBOL_INTERNER.write().unwrap().insert(id.0, v.to_string());
145 id
146 },
147 }
148 }
149
150 pub fn get(
151 &self,
152 id: SymbolId,
153 ) -> Rc<str> {
154 self.symbol_map.get(id).clone()
155 }
156}