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