1#[macro_export]
2macro_rules! format_pl_smallstr {
3 ($($arg:tt)*) => {{
4 use std::fmt::Write;
5
6 let mut string = $crate::pl_str::PlSmallStr::EMPTY;
7 write!(string, $($arg)*).unwrap();
8 string
9 }}
10}
11
12type Inner = compact_str::CompactString;
13
14#[derive(Clone, Eq, Hash, PartialOrd, Ord)]
16#[cfg_attr(
17 feature = "serde",
18 derive(serde::Serialize, serde::Deserialize),
19 serde(transparent)
20)]
21pub struct PlSmallStr(Inner);
22
23impl PlSmallStr {
24 pub const EMPTY: Self = Self::from_static("");
25 pub const EMPTY_REF: &'static Self = &Self::from_static("");
26
27 #[inline(always)]
28 pub const fn from_static(s: &'static str) -> Self {
29 Self(Inner::const_new(s))
30 }
31
32 #[inline(always)]
33 #[allow(clippy::should_implement_trait)]
34 pub fn from_str(s: &str) -> Self {
35 Self(Inner::from(s))
36 }
37
38 #[inline(always)]
39 pub fn from_string(s: String) -> Self {
40 Self(Inner::from(s))
41 }
42
43 #[inline(always)]
44 pub fn as_str(&self) -> &str {
45 self.0.as_str()
46 }
47
48 #[inline(always)]
49 pub fn into_string(self) -> String {
50 self.0.into_string()
51 }
52}
53
54impl Default for PlSmallStr {
55 #[inline(always)]
56 fn default() -> Self {
57 Self::EMPTY
58 }
59}
60
61impl AsRef<str> for PlSmallStr {
64 #[inline(always)]
65 fn as_ref(&self) -> &str {
66 self.as_str()
67 }
68}
69
70impl core::ops::Deref for PlSmallStr {
71 type Target = str;
72
73 #[inline(always)]
74 fn deref(&self) -> &Self::Target {
75 self.as_str()
76 }
77}
78
79impl core::borrow::Borrow<str> for PlSmallStr {
80 #[inline(always)]
81 fn borrow(&self) -> &str {
82 self.as_str()
83 }
84}
85
86impl AsRef<std::path::Path> for PlSmallStr {
89 #[inline(always)]
90 fn as_ref(&self) -> &std::path::Path {
91 self.as_str().as_ref()
92 }
93}
94
95impl AsRef<[u8]> for PlSmallStr {
96 #[inline(always)]
97 fn as_ref(&self) -> &[u8] {
98 self.as_str().as_bytes()
99 }
100}
101
102impl AsRef<std::ffi::OsStr> for PlSmallStr {
103 #[inline(always)]
104 fn as_ref(&self) -> &std::ffi::OsStr {
105 self.as_str().as_ref()
106 }
107}
108
109impl From<&str> for PlSmallStr {
112 #[inline(always)]
113 fn from(value: &str) -> Self {
114 Self::from_str(value)
115 }
116}
117
118impl From<String> for PlSmallStr {
119 #[inline(always)]
120 fn from(value: String) -> Self {
121 Self::from_string(value)
122 }
123}
124
125impl From<&String> for PlSmallStr {
126 #[inline(always)]
127 fn from(value: &String) -> Self {
128 Self::from_str(value.as_str())
129 }
130}
131
132impl From<Inner> for PlSmallStr {
133 #[inline(always)]
134 fn from(value: Inner) -> Self {
135 Self(value)
136 }
137}
138
139impl FromIterator<PlSmallStr> for PlSmallStr {
142 #[inline(always)]
143 fn from_iter<T: IntoIterator<Item = PlSmallStr>>(iter: T) -> Self {
144 Self(Inner::from_iter(iter.into_iter().map(|x| x.0)))
145 }
146}
147
148impl<'a> FromIterator<&'a PlSmallStr> for PlSmallStr {
149 #[inline(always)]
150 fn from_iter<T: IntoIterator<Item = &'a PlSmallStr>>(iter: T) -> Self {
151 Self(Inner::from_iter(iter.into_iter().map(|x| x.as_str())))
152 }
153}
154
155impl FromIterator<char> for PlSmallStr {
156 #[inline(always)]
157 fn from_iter<I: IntoIterator<Item = char>>(iter: I) -> PlSmallStr {
158 Self(Inner::from_iter(iter))
159 }
160}
161
162impl<'a> FromIterator<&'a char> for PlSmallStr {
163 #[inline(always)]
164 fn from_iter<I: IntoIterator<Item = &'a char>>(iter: I) -> PlSmallStr {
165 Self(Inner::from_iter(iter))
166 }
167}
168
169impl<'a> FromIterator<&'a str> for PlSmallStr {
170 #[inline(always)]
171 fn from_iter<I: IntoIterator<Item = &'a str>>(iter: I) -> PlSmallStr {
172 Self(Inner::from_iter(iter))
173 }
174}
175
176impl FromIterator<String> for PlSmallStr {
177 #[inline(always)]
178 fn from_iter<I: IntoIterator<Item = String>>(iter: I) -> PlSmallStr {
179 Self(Inner::from_iter(iter))
180 }
181}
182
183impl FromIterator<Box<str>> for PlSmallStr {
184 #[inline(always)]
185 fn from_iter<I: IntoIterator<Item = Box<str>>>(iter: I) -> PlSmallStr {
186 Self(Inner::from_iter(iter))
187 }
188}
189
190impl<'a> FromIterator<std::borrow::Cow<'a, str>> for PlSmallStr {
191 #[inline(always)]
192 fn from_iter<I: IntoIterator<Item = std::borrow::Cow<'a, str>>>(iter: I) -> PlSmallStr {
193 Self(Inner::from_iter(iter))
194 }
195}
196
197impl<T> PartialEq<T> for PlSmallStr
200where
201 T: AsRef<str> + ?Sized,
202{
203 #[inline(always)]
204 fn eq(&self, other: &T) -> bool {
205 self.as_str() == other.as_ref()
206 }
207}
208
209impl PartialEq<PlSmallStr> for &str {
210 #[inline(always)]
211 fn eq(&self, other: &PlSmallStr) -> bool {
212 *self == other.as_str()
213 }
214}
215
216impl PartialEq<PlSmallStr> for String {
217 #[inline(always)]
218 fn eq(&self, other: &PlSmallStr) -> bool {
219 self.as_str() == other.as_str()
220 }
221}
222
223impl core::fmt::Write for PlSmallStr {
226 #[inline(always)]
227 fn write_char(&mut self, c: char) -> std::fmt::Result {
228 self.0.write_char(c)
229 }
230
231 #[inline(always)]
232 fn write_fmt(&mut self, args: std::fmt::Arguments<'_>) -> std::fmt::Result {
233 self.0.write_fmt(args)
234 }
235
236 #[inline(always)]
237 fn write_str(&mut self, s: &str) -> std::fmt::Result {
238 self.0.write_str(s)
239 }
240}
241
242impl core::fmt::Debug for PlSmallStr {
245 #[inline(always)]
246 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
247 self.as_str().fmt(f)
248 }
249}
250
251impl core::fmt::Display for PlSmallStr {
252 #[inline(always)]
253 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
254 self.as_str().fmt(f)
255 }
256}