tracexec_core/
cache.rs

1use std::{
2  borrow::Cow,
3  fmt::{
4    Debug,
5    Display,
6  },
7  ops::Deref,
8  sync::LazyLock,
9};
10
11use internment::ArcIntern;
12use serde::{
13  Serialize,
14  Serializer,
15};
16
17#[repr(transparent)]
18#[derive(Clone)]
19pub struct ArcStr(ArcIntern<String>);
20
21impl ArcStr {
22  pub fn as_str(&self) -> &str {
23    &self.0
24  }
25}
26
27impl Deref for ArcStr {
28  type Target = str;
29
30  fn deref(&self) -> &Self::Target {
31    &self.0
32  }
33}
34
35impl AsRef<str> for ArcStr {
36  fn as_ref(&self) -> &str {
37    &self.0
38  }
39}
40
41impl<T> PartialEq<T> for ArcStr
42where
43  T: AsRef<str>,
44{
45  fn eq(&self, other: &T) -> bool {
46    *self.0 == other.as_ref()
47  }
48}
49
50impl Eq for ArcStr {}
51
52impl From<ArcStr> for Cow<'_, str> {
53  fn from(value: ArcStr) -> Self {
54    Self::Owned(value.to_string())
55  }
56}
57
58impl Serialize for ArcStr {
59  fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
60  where
61    S: Serializer,
62  {
63    serializer.serialize_str(&self.0)
64  }
65}
66
67impl std::hash::Hash for ArcStr {
68  fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
69    self.0.hash(state);
70  }
71}
72
73impl PartialOrd for ArcStr {
74  fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
75    Some(self.cmp(other))
76  }
77}
78
79impl Ord for ArcStr {
80  fn cmp(&self, other: &Self) -> std::cmp::Ordering {
81    self.0.cmp(&other.0)
82  }
83}
84
85impl Display for ArcStr {
86  fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
87    Display::fmt(&self.0, f)
88  }
89}
90
91impl Debug for ArcStr {
92  fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
93    Debug::fmt(&self.0, f)
94  }
95}
96
97impl From<&str> for ArcStr {
98  fn from(value: &str) -> Self {
99    Self(ArcIntern::from_ref(value))
100  }
101}
102
103impl Default for ArcStr {
104  fn default() -> Self {
105    DEFAULT_ARCSTR.clone()
106  }
107}
108
109static DEFAULT_ARCSTR: LazyLock<ArcStr> = LazyLock::new(|| ArcStr(ArcIntern::from_ref("")));
110
111#[derive(Default)]
112pub struct StringCache;
113
114impl StringCache {
115  pub fn new() -> Self {
116    Self
117  }
118
119  pub fn get_or_insert(&self, s: &str) -> ArcStr {
120    ArcStr(ArcIntern::from_ref(s))
121  }
122
123  // Probably this is not necessary.
124  // I don't think we can find a way to turn a String into Arc<str> in-place.
125  pub fn get_or_insert_owned(&self, s: String) -> ArcStr {
126    ArcStr(ArcIntern::new(s))
127  }
128}