1use std::borrow::Borrow;
2use std::fmt::{self, Debug, Display, Formatter};
3use std::hash::{Hash, Hasher};
4use std::ops::Deref;
5use std::sync::Arc;
6
7#[derive(Clone, Eq)]
11pub enum UStr {
12 Static(&'static str),
13 Shared(Arc<str>),
14}
15
16impl UStr {
17 pub fn new(s: &str) -> Self {
18 UStr::Shared(Arc::from(s.to_owned()))
19 }
20
21 pub fn strip_prefix(this: &Self, prefix: &str) -> Option<Self> {
23 match this {
24 UStr::Static(s) => s.strip_prefix(prefix).map(Self::Static),
25 UStr::Shared(s) => s.strip_prefix(prefix).map(|s| Self::Shared(s.into())),
26 }
27 }
28}
29
30impl Deref for UStr {
31 type Target = str;
32
33 #[inline]
34 fn deref(&self) -> &str {
35 match self {
36 UStr::Static(s) => s,
37 UStr::Shared(s) => s,
38 }
39 }
40}
41
42impl Hash for UStr {
43 #[inline]
44 fn hash<H: Hasher>(&self, state: &mut H) {
45 (**self).hash(state);
48 }
49}
50
51impl Borrow<str> for UStr {
52 #[inline]
53 fn borrow(&self) -> &str {
54 self
55 }
56}
57
58impl PartialEq<UStr> for UStr {
59 fn eq(&self, other: &UStr) -> bool {
60 (**self).eq(&**other)
61 }
62}
63
64impl From<&'static str> for UStr {
65 #[inline]
66 fn from(s: &'static str) -> Self {
67 UStr::Static(s)
68 }
69}
70
71impl<'a> From<&'a UStr> for UStr {
72 fn from(value: &'a UStr) -> Self {
73 value.clone()
74 }
75}
76
77impl From<String> for UStr {
78 #[inline]
79 fn from(s: String) -> Self {
80 UStr::Shared(s.into())
81 }
82}
83
84impl Debug for UStr {
85 #[inline]
86 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
87 f.pad(self)
88 }
89}
90
91impl Display for UStr {
92 #[inline]
93 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
94 f.pad(self)
95 }
96}
97
98#[cfg(feature = "offline")]
101impl<'de> serde::Deserialize<'de> for UStr {
102 fn deserialize<D>(deserializer: D) -> Result<Self, <D as serde::Deserializer<'de>>::Error>
103 where
104 D: serde::Deserializer<'de>,
105 {
106 Ok(String::deserialize(deserializer)?.into())
107 }
108}
109
110#[cfg(feature = "offline")]
111impl serde::Serialize for UStr {
112 fn serialize<S>(
113 &self,
114 serializer: S,
115 ) -> Result<<S as serde::Serializer>::Ok, <S as serde::Serializer>::Error>
116 where
117 S: serde::Serializer,
118 {
119 serializer.serialize_str(self)
120 }
121}