1use serde::{Deserialize, Deserializer, Serialize, Serializer};
9use std::borrow::Cow;
10use std::fmt;
11use std::ops::Deref;
12use std::sync::Arc;
13
14#[derive(Clone, Eq)]
15pub enum TitanString<'a> {
16 Borrowed(&'a str),
17 Owned(String),
18 Shared(Arc<str>),
19}
20
21impl TitanString<'_> {
22 #[must_use]
23 pub fn into_owned(self) -> String {
24 match self {
25 Self::Borrowed(s) => s.to_owned(),
26 Self::Owned(s) => s,
27 Self::Shared(s) => s.to_string(),
28 }
29 }
30
31 #[must_use]
32 pub fn into_shared(self) -> Arc<str> {
33 match self {
34 Self::Borrowed(s) => Arc::from(s),
35 Self::Owned(s) => Arc::from(s),
36 Self::Shared(s) => s,
37 }
38 }
39
40 #[inline]
42 #[must_use]
43 pub fn as_str(&self) -> &str {
44 self
45 }
46}
47
48impl Deref for TitanString<'_> {
49 type Target = str;
50
51 fn deref(&self) -> &Self::Target {
52 match self {
53 Self::Borrowed(s) => s,
54 Self::Owned(s) => s,
55 Self::Shared(s) => s,
56 }
57 }
58}
59
60impl fmt::Debug for TitanString<'_> {
61 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
62 fmt::Debug::fmt(&**self, f)
63 }
64}
65
66impl fmt::Display for TitanString<'_> {
67 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
68 fmt::Display::fmt(&**self, f)
69 }
70}
71
72impl PartialEq for TitanString<'_> {
73 fn eq(&self, other: &Self) -> bool {
74 **self == **other
75 }
76}
77
78impl PartialEq<str> for TitanString<'_> {
79 fn eq(&self, other: &str) -> bool {
80 &**self == other
81 }
82}
83
84impl PartialEq<&str> for TitanString<'_> {
85 fn eq(&self, other: &&str) -> bool {
86 &**self == *other
87 }
88}
89
90impl PartialEq<String> for TitanString<'_> {
91 fn eq(&self, other: &String) -> bool {
92 &**self == other.as_str()
93 }
94}
95
96impl<'a> PartialEq<TitanString<'a>> for String {
97 fn eq(&self, other: &TitanString<'a>) -> bool {
98 self.as_str() == &**other
99 }
100}
101
102impl std::hash::Hash for TitanString<'_> {
103 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
104 (**self).hash(state);
105 }
106}
107
108impl Serialize for TitanString<'_> {
109 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
110 where
111 S: Serializer,
112 {
113 serializer.serialize_str(self)
114 }
115}
116
117impl<'de> Deserialize<'de> for TitanString<'_> {
118 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
119 where
120 D: Deserializer<'de>,
121 {
122 let s = String::deserialize(deserializer)?;
123 Ok(TitanString::Owned(s))
124 }
125}
126
127impl<'a> From<&'a str> for TitanString<'a> {
128 fn from(s: &'a str) -> Self {
129 Self::Borrowed(s)
130 }
131}
132
133impl From<String> for TitanString<'_> {
134 fn from(s: String) -> Self {
135 Self::Owned(s)
136 }
137}
138
139impl From<Arc<str>> for TitanString<'_> {
140 fn from(s: Arc<str>) -> Self {
141 Self::Shared(s)
142 }
143}
144
145impl<'a> From<Cow<'a, str>> for TitanString<'a> {
146 fn from(cow: Cow<'a, str>) -> Self {
147 match cow {
148 Cow::Borrowed(s) => Self::Borrowed(s),
149 Cow::Owned(s) => Self::Owned(s),
150 }
151 }
152}
153
154impl<'a> From<&'a String> for TitanString<'a> {
155 #[inline]
156 fn from(s: &'a String) -> Self {
157 Self::Borrowed(s.as_str())
158 }
159}
160
161impl Default for TitanString<'_> {
162 fn default() -> Self {
163 Self::Borrowed("")
164 }
165}