stringtheory/interning/
mod.rs1use std::ops::Deref;
3
4pub(crate) mod fixed_size;
5pub use self::fixed_size::FixedSizeInterner;
6
7pub(crate) mod helpers;
8
9pub(crate) mod map;
10pub use self::map::GenericMapInterner;
11
12#[cfg(test)]
13pub(crate) mod test_support;
14
15pub trait Interner {
17 fn is_empty(&self) -> bool;
19
20 fn len(&self) -> usize;
22
23 fn len_bytes(&self) -> usize;
25
26 fn capacity_bytes(&self) -> usize;
28
29 fn try_intern(&self, s: &str) -> Option<InternedString>;
33}
34
35impl<T> Interner for &T
36where
37 T: Interner,
38{
39 fn is_empty(&self) -> bool {
40 (**self).is_empty()
41 }
42
43 fn len(&self) -> usize {
44 (**self).len()
45 }
46
47 fn len_bytes(&self) -> usize {
48 (**self).len_bytes()
49 }
50
51 fn capacity_bytes(&self) -> usize {
52 (**self).capacity_bytes()
53 }
54
55 fn try_intern(&self, s: &str) -> Option<InternedString> {
56 (**self).try_intern(s)
57 }
58}
59
60#[derive(Clone, Debug, PartialEq)]
61pub(crate) enum InternedStringState {
62 GenericMap(self::map::StringState),
63 FixedSize(self::fixed_size::StringState),
64}
65
66impl InternedStringState {
67 #[inline]
68 fn as_str(&self) -> &str {
69 match self {
70 Self::GenericMap(state) => state.as_str(),
71 Self::FixedSize(state) => state.as_str(),
72 }
73 }
74}
75
76impl From<self::fixed_size::StringState> for InternedStringState {
77 fn from(state: self::fixed_size::StringState) -> Self {
78 Self::FixedSize(state)
79 }
80}
81
82impl From<self::map::StringState> for InternedStringState {
83 fn from(state: self::map::StringState) -> Self {
84 Self::GenericMap(state)
85 }
86}
87
88#[derive(Clone, Debug, PartialEq)]
93pub struct InternedString {
94 state: InternedStringState,
95}
96
97impl InternedString {
98 pub(crate) fn into_state(self) -> InternedStringState {
99 self.state
100 }
101}
102
103impl<T> From<T> for InternedString
104where
105 T: Into<InternedStringState>,
106{
107 fn from(state: T) -> Self {
108 Self { state: state.into() }
109 }
110}
111
112impl Deref for InternedString {
113 type Target = str;
114
115 fn deref(&self) -> &str {
116 self.state.as_str()
117 }
118}
119
120#[cfg(test)]
121mod tests {
122 use super::*;
123
124 #[test]
125 fn size_of_interned_string() {
126 assert_eq!(std::mem::size_of::<InternedString>(), 24);
130 }
131}