]> git.proxmox.com Git - cargo.git/blob - src/cargo/core/interning.rs
fix more typos (codespell)
[cargo.git] / src / cargo / core / interning.rs
1 use serde::{Serialize, Serializer};
2
3 use std::borrow::Borrow;
4 use std::cmp::Ordering;
5 use std::collections::HashSet;
6 use std::fmt;
7 use std::hash::{Hash, Hasher};
8 use std::ops::Deref;
9 use std::ptr;
10 use std::str;
11 use std::sync::Mutex;
12
13 pub fn leak(s: String) -> &'static str {
14 Box::leak(s.into_boxed_str())
15 }
16
17 lazy_static::lazy_static! {
18 static ref STRING_CACHE: Mutex<HashSet<&'static str>> = Mutex::new(HashSet::new());
19 }
20
21 #[derive(Clone, Copy)]
22 pub struct InternedString {
23 inner: &'static str,
24 }
25
26 impl PartialEq for InternedString {
27 fn eq(&self, other: &InternedString) -> bool {
28 ptr::eq(self.as_str(), other.as_str())
29 }
30 }
31
32 impl Eq for InternedString {}
33
34 impl InternedString {
35 pub fn new(str: &str) -> InternedString {
36 let mut cache = STRING_CACHE.lock().unwrap();
37 let s = cache.get(str).cloned().unwrap_or_else(|| {
38 let s = leak(str.to_string());
39 cache.insert(s);
40 s
41 });
42
43 InternedString { inner: s }
44 }
45
46 pub fn as_str(&self) -> &'static str {
47 self.inner
48 }
49 }
50
51 impl Deref for InternedString {
52 type Target = str;
53
54 fn deref(&self) -> &'static str {
55 self.as_str()
56 }
57 }
58
59 impl Hash for InternedString {
60 // N.B., we can't implement this as `identity(self).hash(state)`,
61 // because we use this for on-disk fingerprints and so need
62 // stability across Cargo invocations.
63 fn hash<H: Hasher>(&self, state: &mut H) {
64 self.as_str().hash(state);
65 }
66 }
67
68 impl Borrow<str> for InternedString {
69 // If we implement Hash as `identity(self).hash(state)`,
70 // then this will need to be removed.
71 fn borrow(&self) -> &str {
72 self.as_str()
73 }
74 }
75
76 impl fmt::Debug for InternedString {
77 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
78 fmt::Debug::fmt(self.as_str(), f)
79 }
80 }
81
82 impl fmt::Display for InternedString {
83 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
84 fmt::Display::fmt(self.as_str(), f)
85 }
86 }
87
88 impl Ord for InternedString {
89 fn cmp(&self, other: &InternedString) -> Ordering {
90 self.as_str().cmp(other.as_str())
91 }
92 }
93
94 impl PartialOrd for InternedString {
95 fn partial_cmp(&self, other: &InternedString) -> Option<Ordering> {
96 Some(self.cmp(other))
97 }
98 }
99
100 impl Serialize for InternedString {
101 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
102 where
103 S: Serializer,
104 {
105 serializer.serialize_str(self.inner)
106 }
107 }